1 /* $Id: fileio.c,v 1.1.1.1.2.1 2000/12/01 10:01:57 amura Exp $ */
2 /*
3  *		sys V fileio.c
4  */
5 
6 /*
7  * $Log: fileio.c,v $
8  * Revision 1.1.1.1.2.1  2000/12/01 10:01:57  amura
9  * fix problems open "/" and sybolic link directory
10  *
11  * Revision 1.1.1.1  2000/06/27 01:47:59  amura
12  * import to CVS
13  *
14  */
15 /* 90.01.29	Modified for Ng 1.0 by S.Yoshida */
16 
17 #include	"config.h"	/* 90.12.20  by S.Yoshida */
18 #include	"def.h"
19 
20 static	FILE	*ffp;
21 extern	char	*getenv();
22 char	*adjustname();
23 
24 #ifdef	SUPPORT_ANSI
25 #include <string.h>
26 #include <unistd.h>
27 #else
28 # ifndef strncpy
29 extern char *strncpy();
30 # endif
31 #endif
32 #include <sys/types.h>
33 #include <sys/wait.h>
34 
35 /*
36  * Open a file for reading.
37  */
ffropen(fn)38 ffropen(fn) char *fn; {
39 	if ((ffp=fopen(fn, "r")) == NULL)
40 		return (FIOFNF);
41 	return (FIOSUC);
42 }
43 
44 /*
45  * Open a file for writing.
46  * Return TRUE if all is well, and
47  * FALSE on error (cannot create).
48  */
ffwopen(fn)49 ffwopen(fn) char *fn; {
50 	if ((ffp=fopen(fn, "w")) == NULL) {
51 		ewprintf("Cannot open file for writing");
52 		return (FIOERR);
53 	}
54 	return (FIOSUC);
55 }
56 
57 /*
58  * Close a file.
59  * Should look at the status.
60  */
ffclose()61 ffclose() {
62 	(VOID) fclose(ffp);
63 	return (FIOSUC);
64 }
65 
66 /*
67  * Write a buffer to the already
68  * opened file. bp points to the
69  * buffer. Return the status.
70  * Check only at the newline and
71  * end of buffer.
72  */
ffputbuf(bp)73 ffputbuf(bp)
74 BUFFER *bp;
75 {
76     register char *cp;
77     register char *cpend;
78     register LINE *lp;
79     register LINE *lpend;
80 #ifdef	KANJI	/* 90.01.30  by S.Yoshida */
81     register int  kfio;
82 #endif	/* KANJI */
83 
84     lpend = bp->b_linep;
85 #ifdef	KANJI	/* 90.02.07  by S.Yoshida */
86     if (bp->b_kfio == NIL)
87 	ksetbufcode(bp);		/* Set buffer local KANJI code.	*/
88     kfio  = bp->b_kfio;
89 #endif	/* KANJI */
90     lp = lforw(lpend);
91     do {
92 	cp = &ltext(lp)[0];		/* begining of line	*/
93 	cpend = &cp[llength(lp)];	/* end of line		*/
94 	while(cp != cpend) {
95 #ifdef	KANJI	/* 90.01.30  by S.Yoshida */
96 	    kputc(*cp, ffp, kfio);
97 #else	/* NOT KANJI */
98 	    putc(*cp, ffp);
99 #endif	/* KANJI */
100 	    cp++;	/* putc may evalualte arguments more than once */
101 	}
102 #ifdef	KANJI	/* 90.01.30  by S.Yoshida */
103 	if (kfio == JIS) {
104 		kfselectcode(ffp, FALSE);
105 	}
106 #endif	/* KANJI */
107 	lp = lforw(lp);
108 	if(lp == lpend) break;		/* no implied newline on last line */
109 	putc('\n', ffp);
110     } while(!ferror(ffp));
111     if(ferror(ffp)) {
112 	ewprintf("Write I/O error");
113 	return FIOERR;
114     }
115     return FIOSUC;
116 }
117 
118 /*
119  * Read a line from a file, and store the bytes
120  * in the supplied buffer. Stop on end of file or end of
121  * line.  When FIOEOF is returned, there is a valid line
122  * of data without the normally implied \n.
123  */
ffgetline(buf,nbuf,nbytes)124 ffgetline(buf, nbuf, nbytes)
125 register char	*buf;
126 register int	nbuf;
127 register int	*nbytes;
128 {
129 	register int	c;
130 	register int	i;
131 
132 	i = 0;
133 	while((c = getc(ffp))!=EOF && c!='\n') {
134 		buf[i++] = c;
135 		if (i >= nbuf) return FIOLONG;
136 	}
137 	if (c == EOF  && ferror(ffp) != FALSE) {
138 		ewprintf("File read error");
139 		return FIOERR;
140 	}
141 	*nbytes = i;
142 	return c==EOF ? FIOEOF : FIOSUC;
143 }
144 
145 #ifndef NO_BACKUP
146 /*
147  * Rename the file "fname" into a backup
148  * copy. On Unix the backup has the same name as the
149  * original file, with a "~" on the end; this seems to
150  * be newest of the new-speak. The error handling is
151  * all in "file.c". The "unlink" is perhaps not the
152  * right thing here; I don't care that much as
153  * I don't enable backups myself.
154  */
fbackupfile(fn)155 fbackupfile(fn) char *fn; {
156 	register char	*nname;
157 
158 	if ((nname=malloc((unsigned)(strlen(fn)+1+1))) == NULL) {
159 		ewprintf("Can't get %d bytes", strlen(fn) + 1);
160 		return (ABORT);
161 	}
162 	(void) strcpy(nname, fn);
163 	(void) strcat(nname, "~");
164 	(void) unlink(nname);			/* Ignore errors.	*/
165 	if (rename(fn, nname) < 0) {
166 		free(nname);
167 		return (FALSE);
168 	}
169 	free(nname);
170 	return (TRUE);
171 }
172 
173 #ifdef	BUGFIX	/* 90.02.14  by S.Yoshida */
174 #ifndef	_SYS_STAT_H_
175 #include <sys/stat.h>
176 #define	_SYS_STAT_H_
177 #endif	/* _SYS_STAT_H_ */
178 /*
179  * Get file mode of a file fn.
180  */
fgetfilemode(fn)181 fgetfilemode(fn)
182 char	*fn;
183 {
184 	struct	stat	filestat;
185 
186 	stat(fn, &filestat);
187 	return(filestat.st_mode & 0x0fff);
188 }
189 
190 /*
191  * Set file mode of a file fn to the specified mode.
192  */
fsetfilemode(fn,mode)193 fsetfilemode(fn, mode)
194 char	*fn;
195 int	mode;
196 {
197 	chmod(fn, mode);
198 }
199 #endif	/* BUGFIX */
200 #endif
201 
202 #ifdef	READONLY	/* 91.01.05  by S.Yoshida */
203 #ifndef	_SYS_STAT_H_
204 #include <sys/stat.h>
205 #define	_SYS_STAT_H_
206 #endif	/* _SYS_STAT_H_ */
207 /*
208  * Check whether file is read-only of a file fn.
209  */
fchkreadonly(fn)210 fchkreadonly(fn)
211 char	*fn;
212 {
213 	struct	stat	filestat;
214 
215 	if (stat(fn, &filestat) == 0) {
216 		return(!(filestat.st_mode & S_IWRITE));
217 	} else {
218 		return FALSE;
219 	}
220 }
221 #endif	/* READONLY */
222 
223 /*
224  * The string "fn" is a file name.
225  * Perform any required appending of directory name or case adjustments.
226  * If NO_DIR is not defined, the same file should be refered to even if the
227  * working directory changes.
228  */
229 #ifdef SYMBLINK
230 #ifndef	BUGFIX		/* 90.02.15  by S.Yoshida: Previously included. */
231 #include <sys/types.h>
232 #endif	/* BUGFIX */
233 #ifndef	_SYS_STAT_H_	/* 90.02.15  by S.Yoshida */
234 #include <sys/stat.h>
235 #define	_SYS_STAT_H_
236 #endif	/* _SYS_STAT_H_ */
237 #ifndef MAXLINK
238 #define MAXLINK 8		/* maximum symbolic links to follow */
239 #endif
240 #endif
241 #include <pwd.h>
242 #ifndef NO_DIR
243 extern char *wdir;
244 #endif
245 
adjustname(fn)246 char *adjustname(fn)
247 register char *fn;
248 {
249     register char *cp;
250     static char fnb[NFILEN];
251     struct passwd *pwent, *getpwnam();
252 #ifdef	SYMBLINK
253     struct stat statbuf;
254     int i, j;
255     char linkbuf[NFILEN];
256 #endif
257 
258     switch(*fn) {
259     	case '/':
260 	    cp = fnb;
261 	    *cp++ = *fn++;
262 	    break;
263 	case '~':
264 	    fn++;
265 	    if(*fn == '/' || *fn == '\0') {
266 		(VOID) strcpy(fnb, getenv("HOME"));
267 		cp = fnb + strlen(fnb);
268 	    	if(*fn) fn++;
269 		break;
270 	    } else {
271 		cp = fnb;
272 		while(*fn && *fn != '/') *cp++ = *fn++;
273 		*cp = '\0';
274 		if((pwent = getpwnam(fnb)) != NULL) {
275 		    (VOID) strcpy(fnb, pwent->pw_dir);
276 		    cp = fnb + strlen(fnb);
277 		    break;
278 		} else {
279 		    fn -= strlen(fnb) + 1;
280 		    /* can't find ~user, continue to default case */
281 		}
282 	    }
283 	default:
284 #ifndef	NODIR
285 	    strcpy(fnb, wdir);
286 	    cp = fnb + strlen(fnb);
287 	    break;
288 #else
289 	    return fn;				/* punt */
290 #endif
291     }
292     if(cp != fnb && cp[-1] != '/') *cp++ = '/';
293     while(*fn) {
294     	switch(*fn) {
295 	    case '.':
296 		switch(fn[1]) {
297 	            case '\0':
298 		    	*--cp = '\0';
299 		    	return fnb;
300 	    	    case '/':
301 	    	    	fn += 2;
302 		    	continue;
303 		    case '.':
304 		    	if(fn[2]=='/' || fn[2] == '\0') {
305 #ifdef SYMBLINK
306 			    cp[-1] = '\0';
307 			    for(j = MAXLINK; j-- &&
308 			    	    lstat(fnb, &statbuf) != -1 &&
309 			    	    (statbuf.st_mode&S_IFMT) == S_IFLNK &&
310 			    	    (i = readlink(fnb, linkbuf, sizeof linkbuf))
311 				    != -1 ;) {
312 				if(linkbuf[0] != '/') {
313 				    --cp;
314 				    while(cp > fnb && *--cp != '/') {}
315 				    ++cp;
316 				    (VOID) strncpy(cp, linkbuf, i);
317 				    cp += i;
318 				} else {
319 				    (VOID) strncpy(fnb, linkbuf, i);
320 				    cp = fnb + i;
321 				}
322 				if(cp[-1]!='/') *cp++ = '\0';
323 				else cp[-1] = '\0';
324 			    }
325 			    cp[-1] = '/';
326 #endif
327 			    --cp;
328 			    while(cp > fnb && *--cp != '/') {}
329 			    ++cp;
330 			    if(fn[2]=='\0') {
331 			        *--cp = '\0';
332 			        return fnb;
333 			    }
334 		            fn += 3;
335 		            continue;
336 		        }
337 		        break;
338 		    default:
339 		    	break;
340 	        }
341 		break;
342 	    case '/':
343 	    	fn++;
344 	    	continue;
345 	    default:
346 	    	break;
347 	}
348 	while(*fn && (*cp++ = *fn++) != '/') {}
349     }
350     if((cp-1)!=fnb && cp[-1]=='/') --cp;
351     *cp = '\0';
352     return fnb;
353 }
354 
355 #ifndef NO_STARTUP
356 #include <sys/file.h>
357 #ifndef F_OK
358 #define F_OK 04			/* for stupid Sys V		*/
359 #endif
360 
361 /*
362  * Find a startup file for the user and return its name. As a service
363  * to other pieces of code that may want to find a startup file (like
364  * the terminal driver in particular), accepts a suffix to be appended
365  * to the startup file name.
366  */
367 char *
368 #ifdef	ADDOPT
startupfile(ngrcfile,suffix)369 startupfile(ngrcfile, suffix)
370 char* ngrcfile;
371 #else
372 startupfile(suffix)
373 #endif
374 char *suffix;
375 {
376 	register char	*file;
377 	static char	home[NFILEN];
378 	char		*getenv();
379 
380 
381 #ifdef	ADDOPT
382 	if (ngrcfile == NULL)
383 		ngrcfile = getenv("NGRC");
384 	if (ngrcfile != NULL)
385 		if (access(ngrcfile, F_OK) == 0)  return ngrcfile;
386 #endif
387 	if ((file = getenv("HOME")) == NULL) goto notfound;
388 	if (strlen(file)+7 >= NFILEN - 1) goto notfound;
389 	(VOID) strcpy(home, file);
390 #ifdef	KANJI	/* 90.02.10  by S.Yoshida */
391 	(VOID) strcat(home, "/.ng");
392 #else	/* NOT KANJI */
393 	(VOID) strcat(home, "/.mg");
394 #endif	/* KANJI */
395 	if (suffix != NULL) {
396 		(VOID) strcat(home, "-");
397 		(VOID) strcat(home, suffix);
398 	}
399 	if (access(home, F_OK) == 0) return home;
400 
401 notfound:
402 #ifdef	STARTUPFILE
403 	file = STARTUPFILE;
404 	if (suffix != NULL) {
405 		(VOID) strcpy(home, file);
406 		(VOID) strcat(home, "-");
407 		(VOID) strcat(home, suffix);
408 		file = home;
409 	}
410 	if (access(file, F_OK ) == 0) return file;
411 #endif
412 
413 	return NULL;
414 }
415 #endif
416 
417 #ifndef NO_DIRED
418 #include "kbd.h"
419 
copy(frname,toname)420 copy(frname, toname)
421 char *frname, *toname;
422 {
423     int pid;
424     int status;
425 
426 #ifdef	BUGFIX	/* 91.01.11  by Y.Kaneko */
427     if((pid = fork()) == 0) {
428 #else	/* ORIGINAL */
429     if(pid = fork()) {
430 	if(pid == -1)	return	-1;
431 #endif	/* BUGFIX */
432 	execl("/bin/cp", "cp", frname, toname, (char *)NULL);
433 	_exit(1);	/* shouldn't happen */
434     }
435 #ifdef	BUGFIX	/* 91.01.11  by Y.Kaneko */
436     if(pid == -1)	return	-1;
437 #endif	/* BUGFIX */
438     while(wait(&status) != pid)
439 	;
440     return status == 0;
441 }
442 
dired_(dirname)443 BUFFER *dired_(dirname)
444 char *dirname;
445 {
446     register BUFFER *bp;
447     char line[256];
448     BUFFER *findbuffer();
449     FILE *dirpipe;
450     FILE *popen();
451 
452     if((dirname = adjustname(dirname)) == NULL) {
453 	ewprintf("Bad directory name");
454 	return NULL;
455     }
456 #ifdef	BUGFIX	/* 90.02.06  by S.Yoshida */
457     if(dirname[strlen(dirname)-1] != '/') (VOID) strcat(dirname, "/");
458 #endif	/* BUGFIX */
459     if((bp = findbuffer(dirname)) == NULL) {
460 	ewprintf("Could not create buffer");
461 	return NULL;
462     }
463     if(bclear(bp) != TRUE) return FALSE;
464 #ifdef	EXTD_DIR
465     strncpy(bp->b_cwd, dirname, NFILEN);
466     ensurecwd();
467 #endif
468 #ifdef	BUGFIX	/* 91.02.04  by M.Oki */
469     (VOID) strcpy(line, "/bin/ls -al ");
470     (VOID) strcpy(&line[12], dirname);
471 #else	/* ORIGINAL */
472     (VOID) strcpy(line, "ls -al ");
473     (VOID) strcpy(&line[7], dirname);
474 #endif	/* BUGFIX */
475     if((dirpipe = popen(line, "r")) == NULL) {
476 	ewprintf("Problem opening pipe to ls");
477 	return NULL;
478     }
479     line[0] = line[1] = ' ';
480     while(fgets(&line[2], 254, dirpipe) != NULL) {
481 	line[strlen(line) - 1] = '\0';		/* remove ^J	*/
482 	(VOID) addline(bp, line);
483     }
484     if(pclose(dirpipe) == -1) {
485 	ewprintf("Problem closing pipe to ls");
486 	return NULL;
487     }
488     bp->b_dotp = lforw(bp->b_linep);		/* go to first line */
489     (VOID) strncpy(bp->b_fname, dirname, NFILEN);
490     if((bp->b_modes[0] = name_mode("dired")) == NULL) {
491 	bp->b_modes[0] = &map_table[0];
492 	ewprintf("Could not find mode dired");
493 	return NULL;
494     }
495     bp->b_nmodes = 0;
496     return bp;
497 }
498 
d_makename(lp,fn)499 d_makename(lp, fn)
500 register LINE *lp;
501 register char **fn;
502 {
503   char* cp;
504   int l,l1,len;
505   char c;
506 
507   /* '56' is a magic number and is not correct always */
508 
509   if ( llength( lp ) <= 56 ) {
510     return ABORT ;
511   }
512   l = llength(lp);
513 
514   if (lgetc(lp, 2) == 'l') {
515     do {
516       while (l > 2 && lgetc(lp, l) != ' ')
517         l--;
518       if (bcmp(lp->l_text + l - 3, " -> ", 4) == 0)
519         break;
520       l--;
521     } while (l > 2);
522   }
523   else {
524     do {
525       while (l > 2 && lgetc(lp, l)!=' ')
526         l--;
527       l1 = l;
528       while (l > 2 && lgetc(lp, l)==' ')
529         l--;
530       while (l > 2 && (c=lgetc(lp, l))!=' ') {
531         if (c!=':' && (c<'0'&&c>'9')) {
532           break;
533         }
534         l--;
535       }
536     } while (l > 2 && c != ' ');
537   l = l1;
538   }
539   if (l <= 2)
540     return ABORT;
541   l++;
542 
543   len = llength(lp) - l + 1;
544   cp = malloc(len + strlen(curbp->b_fname) + 1);
545   if (cp) {
546     *fn = cp;
547     strcpy(cp, curbp->b_fname);
548     cp += strlen(cp);
549     bcopy(lp->l_text + l, cp, len);
550     cp[len-1] = '\0';
551 #ifdef	SYMBLINK
552     if (lgetc(lp, 2) == 'l')
553       return ffisdir(curbp->b_fname);
554 #endif
555     return lgetc(lp, 2) == 'd';
556   }
557   else {
558     return ABORT;
559   }
560 }
561 
562 /*
563  * I, a System V novice, could only figure out how to do unlinkdir()
564  * and rename() as exec's of the appropriate functions.  So sue me.
565  * --Stephen Walton, December 1987
566  *
567  * Now, SystemV has rmdir (form Release3) and rename (form Release 4).
568  * I rewrite Ng use them.
569  * --amura, 03 Apr 2000
570  */
571 
572 #ifdef SVR2
unlinkdir(f)573 unlinkdir(f)	/* System V Release 2 don't have rmdir(2)? */
574 char *f;
575 {
576 	int status, pid, wpid;
577 
578 	if ((pid = fork()) == 0)
579 		execl("/bin/rmdir", "rmdir", f, (char *)NULL);
580 	else if (pid > 0)
581 		while ((wpid = wait(&status)) && wpid != pid)
582 			;
583 	else
584 		return FALSE;
585 	return status == 0;
586 }
587 #endif
588 
589 #ifndef SVR4
rename(f1,f2)590 rename(f1, f2)	/* System V Release 2/3 don't have rename(2)? */
591 char *f1, *f2;
592 {
593 
594 	int status, pid, wpid;
595 
596 	if ((pid = fork()) == 0)
597 		execl("/bin/mv", "mv", f1, f2, (char *)NULL);
598 	else if (pid > 0)
599 		while ((wpid = wait(&status)) && wpid != pid)
600 			;
601 	else
602 		return FALSE;
603 	return status == 0;
604 }
605 #endif /* SVR4 */
606 #endif /* NO_DIRED */
607 
608 #ifndef NO_DIRED	/* 91.01.15  by K.Maeda */
609 #ifndef	_SYS_STAT_H_
610 #include <sys/stat.h>
611 #define	_SYS_STAT_H_
612 #endif	/* _SYS_STAT_H_ */
613 /*
614  * Check whether file "dn" is directory.
615  */
ffisdir(dn)616 ffisdir(dn)
617 char *dn;
618 {
619 	struct	stat	filestat;
620 
621 	if (stat(dn, &filestat) == 0) {
622 		return ((filestat.st_mode & S_IFMT) == S_IFDIR);
623 	} else {
624 		return FALSE;
625 	}
626 }
627 #endif /* NO_DIRED */
628 
629 #ifndef NO_FILECOMP	/* 90.04.04  by K.Maeda */
630 #ifndef	SVR2		/* 91.01.29  SVR3 or later. by S.Yoshida */
631 #include <dirent.h>	/* 90.07.16  <sys/dir.h> -> <dirent.h> by Y.Nimura */
632 #else	/* SVR2 */
633 #include <sys/dir.h>
634 #include <fcntl.h>
635 #endif	/* SVR2 */
636 
637 /* 89.11.20	Original code is for X68K (Human68K).
638  * 90.07.05	Modified for System V UNIX by S.Yoshida
639  *		This routine may be compiled only in SysV Rel 3 or later.
640  * 90.07.16	Debuged by Y.Nimura.
641  * 91.01.29	Debug for SysV Rel 2. by S.Yoshida
642  * Find file names starting with name.
643  * Result is stored in *buf, got from malloc();
644  * Return the number of files found, or
645  * -1 of error occured.
646  */
647 
648 #define	MALLOC_STEP	256
649 
fffiles(name,buf)650 fffiles(name, buf)
651 char *name, **buf;
652 {
653 	char pathbuf[128], tmpnam[128];
654 	char *cp, *dirpart, *nampart;
655 #ifndef	SVR2	/* 91.01.29  SVR3 or later. by S.Yoshida */
656 	/* 90.07.16  direct -> dirent by Y.Nimura */
657 	DIR *dp;
658 	register struct dirent *dirent;
659 #else	/* SVR2 */
660 	int dp;
661 	struct direct dirbuf;
662 	register struct direct *dirent = &dirbuf;
663 #endif	/* SVR2 */
664 	int n, len, size, dirpartlen, nampartlen;
665 	char *buffer;
666 	struct stat st;
667 
668 	strcpy(pathbuf, name);
669 	dirpart = NULL;
670 	for (cp = pathbuf; *cp; cp++) {
671 		if (*cp == '/')
672 			dirpart = cp;
673 	}
674 	if (dirpart) {
675 		*++dirpart = '\0';
676 		dirpartlen = dirpart-pathbuf;
677 	} else {
678 		strcpy(pathbuf, "./");
679 		dirpartlen = 0;
680 	}
681 	nampart = name + dirpartlen;
682 	nampartlen = strlen(nampart);
683 
684 #ifndef	NEW_COMPLETE	/* 90.12.10    Sawayanagi Yosirou */
685 #ifndef SVR2	/* 91.02.04  SVR3 or later. by Y.Nimura */
686 	if ((dp = opendir(pathbuf)) == NULL)
687 #else	/* SVR2 */
688 	if ((dp = open(pathbuf,O_RDONLY)) < 0)
689 #endif	/* SVR2 */
690 		return -1;
691 #endif	/* NOT NEW_COMPLETE */
692 
693 	buffer = malloc(MALLOC_STEP);
694 	if (buffer == NULL)
695 		return -1;
696 	size = MALLOC_STEP;
697 	len = 0; n = 0;
698 
699 #ifdef	NEW_COMPLETE	/* 90.12.10    Sawayanagi Yosirou */
700 #ifndef SVR2	/* 91.02.04  SVR3 or later. by Y.Nimura */
701 	if ((dp = opendir(pathbuf)) == NULL) {
702 #else	/* SVR2 */
703 	if ((dp = open(pathbuf,O_RDONLY)) < 0) {
704 #endif	/* SVR2 */
705 		*buf = buffer;
706 		buffer[0] = '\0';
707 		return 0;
708 	}
709 #endif	/* NEW_COMPLETE */
710 
711 #ifndef	SVR2	/* 91.02.04  SVR3 or later. by Y.Nimura */
712 	while ((dirent = readdir(dp)) != NULL) {
713 #else	/* SVR2 */
714 	while (read(dp,dirent,sizeof(struct direct)) == sizeof(struct direct)) {
715 #endif	/* SVR2 */
716 		register int l;
717 #ifdef	SVR2	/* 91.02.04  by Y.Nimura */
718 		if (dirent->d_ino == 0) continue;
719 #endif	/* SVR2 */
720 		if (strncmp(nampart, dirent->d_name, nampartlen) != 0)
721 			goto nomatch;		/* case-sensitive comparison */
722 		strncpy(tmpnam, pathbuf, dirpartlen);
723 		strcpy(tmpnam+dirpartlen, dirent->d_name);
724 		if (stat(tmpnam, &st) < -1) goto nomatch;
725 		if ((st.st_mode & S_IFMT)==S_IFDIR)
726 			strcat(tmpnam, "/");
727 		l = strlen(tmpnam)+1;
728 		if (l > 3 && tmpnam[l-3] == '.' && tmpnam[l-2] == 'o')
729 			goto nomatch;
730 		if (l+len >= size) {
731 				/* make room for double null */
732 			if ((buffer = realloc(buffer, size += MALLOC_STEP)) == NULL)
733 				return -1;
734 		}
735 		strcpy(buffer+len, tmpnam);
736 		len += l;
737 		n++;
738 	nomatch:;
739 	}
740 #ifndef SVR2	/* 91.02.04  SVR3 or later. by Y.Nimura */
741 	closedir(dp);
742 #else	/* SVR2 */
743 	close(dp);
744 #endif	/* SVR2 */
745 
746 	*buf = buffer;
747 	buffer[len] = '\0';
748 	return n;
749 }
750 #endif
751 
752 #ifdef	NEW_COMPLETE	/* 90.12.10    Sawayanagi Yosirou */
753 char *
file_name_part(s)754 file_name_part (s)
755     char    *s;
756 {
757     int    i;
758 
759     for (i = strlen (s); i > 0; i--)
760       {
761         if (s[i - 1] == '/')
762 	  break;
763       }
764     return (s + i);
765 }
766 
767 char *
copy_dir_name(d,s)768 copy_dir_name (d, s)
769     char    *d;
770     char    *s;
771 {
772     int    i;
773 
774     i = file_name_part (s) - s;
775     strncpy (d, s, i);
776     d[i] = '\0';
777     return (d);
778 }
779 #endif	/* NEW_COMPLETE */
780