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 = <ext(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