📄 fileio.c
字号:
d->fab.fab$l_nam = &d->nam; /* fab -> nam */ d->fab.fab$l_fna = p; /* argument wild name */ d->fab.fab$b_fns = strlen(p); /* length */ d->nam.nam$l_esa = d->d_qualwildname; /* qualified wild name */ d->nam.nam$b_ess = NAM$C_MAXRSS; /* max length */ d->nam.nam$l_rsa = d->d_name; /* matching file name */ d->nam.nam$b_rss = NAM$C_MAXRSS; /* max length */ /* parse the file name */ if (sys$parse(&d->fab) != RMS$_NORMAL) return; /* Does this replace d->fab.fab$l_fna with a new string in its own space? I sure hope so, since p is free'ed before this routine returns. */ /* have qualified wild name (i.e., disk:[dir.subdir]*.*); null-terminate * and set wild-flag */ d->d_qualwildname[d->nam.nam$b_esl] = '\0'; d->d_wild = (d->nam.nam$l_fnb & NAM$M_WILDCARD)? 1 : 0; /* not used... */#ifdef DEBUG fprintf(mesg, " incoming wildname: %s\n", p); fprintf(mesg, " qualified wildname: %s\n", d->d_qualwildname);#endif /* DEBUG */}dstrm *opendir(n)char *n; /* directory to open *//* Start searching for files in the VMS directory n */{ char *c; /* scans VMS path */ dstrm *d; /* malloc'd return value */ int m; /* length of name */ char *p; /* malloc'd temporary string */ if ((d = (dstrm *)malloc(sizeof(dstrm))) == NULL || (p = malloc((m = strlen(n)) + 4)) == NULL) return NULL; /* Directory may be in form "[DIR.SUB1.SUB2]" or "[DIR.SUB1]SUB2.DIR;1". If latter, convert to former. */ if (m > 0 && *(c = strcpy(p,n)+m-1) != ']') { while (--c > p && *c != ';') ; if (c-p < 5 || strncmp(c-4, ".DIR", 4)) { free((voidp *)d); free((voidp *)p); return NULL; } c -= 3; *c-- = '\0'; /* terminate at "DIR;#" */ *c = ']'; /* "." --> "]" */ while (c > p && *--c != ']') ; *c = '.'; /* "]" --> "." */ } strcat(p, "*.*"); strcat(p, wild_version_part); vms_wild(p, d); /* set up wildcard */ free((voidp *)p); return d;}struct direct *readdir(d)dstrm *d; /* directory stream to read from *//* Return pointer to first or next directory entry, or NULL if end. */{ int r; /* return code */ do { d->fab.fab$w_ifi = 0; /* internal file index: what does this do? */ /* get next match to possible wildcard */ if ((r = sys$search(&d->fab)) == RMS$_NORMAL) { d->d_name[d->nam.nam$b_rsl] = '\0'; /* null terminate */ return (struct direct *)d; /* OK */ } } while (r == RMS$_PRV); return NULL;}# define closedir free#endif /* VMS */#ifdef NODIR /* for AT&T 3B1 *//*** Apparently originally by Rich Salz.** Cleaned up and modified by James W. Birdsall.*/# define opendir(path) fopen(path, "r") struct direct *readdir(dirp)DIR *dirp;{ static struct direct entry; if (dirp == NULL) return NULL; for (;;) if (fread (&entry, sizeof (struct direct), 1, dirp) == 0) return NULL; else if (entry.d_ino) return (&entry);} /* end of readdir() */# define closedir(dirp) fclose(dirp)#endif /* NODIR */#ifdef DIRENT# ifdef TOPS20local dstrm *opend(n)char *n; /* directory name to open *//* Open the directory *n, returning a pointer to an allocated dstrm, or NULL if error. */{ dstrm *d; /* pointer to malloc'ed directory stream */ char *c; /* scans TOPS20 path */ int m; /* length of name */ char *p; /* temp string */ if (((d = (dstrm *)malloc(sizeof(dstrm))) == NULL) || ((p = (char *)malloc((m = strlen(n)) + 4)) == NULL)) { return NULL; }/* Directory may be in form "<DIR.SUB1.SUB2>" or "<DIR.SUB1>SUB2.DIRECTORY".** If latter, convert to former. */ if ((m > 0) && (*(c = strcpy(p,n) + m-1) != '>')) { c -= 10; *c-- = '\0'; /* terminate at "DIRECTORY.1" */ *c = '>'; /* "." --> ">" */ while ((c > p) && (*--c != '>')); *c = '.'; /* ">" --> "." */ } strcat(p, "*.*"); if ((d->wfjfn = wfopen(p)) == 0) { free((voidp *)d); free((voidp *)p); return NULL; } free((voidp *)p); d->more = TRUE; return (d);}#else /* !TOPS20 */local dstrm *opend(n)char *n; /* directory name to open *//* Open the directory *n, returning a pointer to an allocated dstrm, or NULL if error. */{ dstrm *d; /* pointer to malloc'ed directory stream */ if ((d = (dstrm *)malloc(sizeof(dstrm))) == NULL) return NULL; if ((d->f = open(n, 0, 0)) < 0) /* open directory */ return NULL; d->p = d->q = d->b; /* buffer is empty */ return d;}# endif /* ?TOPS20 */#else /* !DIRENT */# define opend opendir /* just use opendir() */#endif /* ?DIRENT */local char *readd(d)dstrm *d; /* directory stream to read from *//* Return a pointer to the next name in the directory stream d, or NULL if no more entries or an error occurs. */{#ifdef TOPS20 char *p; if ((d->more == FALSE) || ((p = wfname(d->wfjfn)) == NULL)) { return NULL; } if (wfnext(d->wfjfn) == 0) { d->more = FALSE; } return p;#else /* !TOPS20 */ struct direct *e; /* directory entry read */# ifdef DIRENT int n; /* number of entries read by getdents */ if (d->p >= d->q) /* if empty, fill buffer */ if ((n = getdents(d->f, d->b, DBSZ)) <= 0) return NULL; else d->q = n + (d->p = d->b); e = (struct direct *)(d->p); /* point to entry */ d->p += ((struct direct *)(d->p))->d_reclen; /* advance */ return e->d_name; /* return name */# else /* !DIRENT */ e = readdir(d); return e == NULL ? (char *)NULL : e->d_name;# endif /* ?DIRENT */#endif /* ?TOPS20 */}#ifdef DIRENTlocal void closed(d)dstrm *d; /* directory stream to close *//* Close the directory stream */{#ifndef TOPS20 close(d->f);#endif free((voidp *)d);}#else /* !DIRENT */# define closed closedir#endif /* ?DIRENT */#ifdef TOPS20/* Wildcard filename routines *//* WFOPEN - open wild card filename** Returns wild JFN for filespec, 0 if failure.*/static intwfopen(name)char *name;{ return (_gtjfn(name, (O_RDONLY | O_T20_WILD)));}/* WFNAME - Return filename for wild JFN** Returns pointer to dynamically allocated filename string*/static char *wfname(jfn)int jfn;{ char *fp, fname[200]; int ablock[5]; ablock[1] = (int) (fname - 1); ablock[2] = jfn & 0777777; /* jfn, no flags */ ablock[3] = 0111110000001; /* DEV+DIR+NAME+TYPE+GEN, punctuate */ if (!jsys(JFNS, ablock)) return NULL; /* something bad happened */ if ((fp = (char *)malloc(strlen(fname) + 1)) == NULL) { return NULL; } strcpy(fp, fname); /* copy the file name here */ return fp;}/* WFNEXT - Make wild JFN point to next real file** Returns success or failure (not JFN)*/static intwfnext(jfn)int jfn;{ int ablock[5]; ablock[1] = jfn; /* save jfn and flags */ return jsys(GNJFN, ablock);}#endif /* TOPS20 */ #ifdef __human68k__int wild(w)char *w;{ struct _filbuf inf; int r; extern int _hupair; char name[FNMAX]; char *p; if (_hupair) return procname(w); /* if argv's passed hupair, don't glob */ strcpy(name, w); _toslash(name); if ((p = strrchr(name, '/')) == NULL && (p = strrchr(name, ':')) == NULL) p = name; else p++; if (_dos_files (&inf, w, 0xff) < 0) return ZE_MISS; do { strcpy(p, inf.name); r = procname(name); if (r != ZE_OK) return r; } while (_dos_nfiles(&inf) >= 0); return ZE_OK;}#endif#if defined(MSDOS) && !defined(OS2) && !defined(WIN32)char *getVolumeLabel(drive, vtime, vmode) int drive; /* drive name: 'A' .. 'Z' or '\0' for current drive */ ulg *vtime; /* volume label creation time (DOS format) */ ulg *vmode; /* volume label file mode *//* If a volume label exists for the given drive, return its name and set its time and mode. The returned name must be static data. */{ static char vol[14]; ff_dir d; if (drive) { vol[0] = (char)drive; strcpy(vol+1, ":/"); } else { strcpy(vol, "/"); } strcat(vol, "*.*"); if (FFIRST(vol, &d, FA_LABEL) == 0) { strncpy(vol, d.ff_name, sizeof(vol)-1); *vtime = ((ulg)d.ff_fdate << 16) | ((ulg)d.ff_ftime & 0xffff); *vmode = (ulg)d.ff_attrib; return vol; } return NULL;}#endif /* MSDOS && !OS2 && !WIN32 */#if defined(MSDOS) || defined(OS2)int wild(w)char *w; /* path/pattern to match *//* If not in exclude mode, expand the pattern based on the contents of the file system. Return an error code in the ZE_ class. */{# ifndef __GO32__ char *a; /* alloc'ed space for name */ dstrm *d; /* stream for reading directory */ char *e; /* name found in directory */ int f; /* true if there was a match */ char *n; /* constructed name from directory */ char *p; /* path */ char *q; /* name */ int r; /* temporary variable */ char v[5]; /* space for device current directory */# endif /* __GO32__ */# ifndef WIN32 if (volume_label == 1) { volume_label = 2; label = getVolumeLabel(w[1] == ':' ? to_up(w[0]) : '\0', &label_time, &label_mode); if (label != NULL) { newname(label, 0); } if (w[1] == ':' && w[2] == '\0') return ZE_OK; /* "zip -$ foo a:" can be used to force drive name */ }# endif# ifdef __GO32__ return procname(w); /* expansion already done by DJGPP */# else /* Allocate and copy pattern */ if ((p = a = malloc(strlen(w) + 1)) == NULL) return ZE_MEM; strcpy(p, w); /* Normalize path delimiter as '/'. */ for (q = p; *q; q++) /* use / consistently */ if (*q == '\\') *q = '/'; /* Only name can have special matching characters */ if ((q = isshexp(p)) != NULL && (strrchr(q, '/') != NULL || strrchr(q, ':') != NULL)) { free((voidp *)a); return ZE_PARMS; } /* Separate path and name into p and q */ if ((q = strrchr(p, '/')) != NULL && (q == p || q[-1] != ':')) { *q++ = 0; /* path/name -> path, name */ if (*p == 0) /* path is just / */ p = strcpy(v, "/."); } else if ((q = strrchr(p, ':')) != NULL) { /* has device and no or root path */ *q++ = 0; p = strcat(strcpy(v, p), ":"); /* copy device as path */ if (*q == '/') /* -> device:/., name */ { strcat(p, "/"); q++; } strcat(p, "."); } else /* no path or device */ { q = p; p = strcpy(v, "."); } /* I can't understand Mark's code so I am adding a hack here to get * "zip -r foo ." to work. Allow the dubious "zip -r foo .." but * reject "zip -rm foo ..". */ if (recurse && (strcmp(q, ".") == 0 || strcmp(q, "..") == 0)) { if (dispose && strcmp(q, "..") == 0) err(ZE_PARMS, "cannot remove parent directory"); return procname(p); } /* Search that level for matching names */ if ((d = opend(p)) == NULL) { free((voidp *)a); return ZE_MISS; } if ((r = strlen(p)) > 1 && (strcmp(p + r - 2, ":.") == 0 || strcmp(p + r - 2, "/.") == 0)) *(p + r - 1) = 0; f = 0; while ((e = readd(d)) != NULL) { if (strcmp(e, ".") && strcmp(e, "..") && MATCH(q, e)) { f = 1; if (strcmp(p, ".") == 0) { /* path is . */ r = procname(e); /* name is name */ if (r) { f = 0; break; } } else { if ((n = malloc(strlen(p) + strlen(e) + 2)) == NULL) { free((voidp *)a); closed(d); return ZE_MEM; } n = strcpy(n, p); if (n[r = strlen(n) - 1] != '/' && n[r] != ':') strcat(n, "/"); r = procname(strcat(n, e)); /* name is path/name */ free((voidp *)n); if (r) { f = 0; break; } } } } closed(d); /* Done */ free((voidp *)a); return f ? ZE_OK : ZE_MISS;# endif /* __GO32__ */}#endif /* MSDOS || OS2 */#if defined(MSDOS) && !defined(OS2) && !defined(WIN32)# if defined(__TURBOC__) || defined(__GO32__) || defined(__BORLANDC__)# define GetFileMode(name) bdosptr(0x43, (name), 0)# else int GetFileMode(char *name) { unsigned int attr = 0; _dos_getfileattr(name, &attr); return attr; }# endif/* __TURBOC__ || __GO32__ */# endif /* MSDOS && !OS2 */#ifdef __human68k__# define GetFileMode(name) (_dos_chmod((name), -1) & 0x3f)#endif#ifdef AMIGA /* What we have here is a mostly-generic routine using opend()/readd() and *//* isshexp()/MATCH() to find all the files matching a multi-part filespec *//* using the portable pattern syntax. It shouldn't take too much fiddling *//* to make it usable for any other platform that has directory hierarchies *//* but no shell-level pattern matching. It works for patterns throughout *//* the pathname, such as "foo:*.?/source/x*.[ch]". */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -