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