📄 fileio.c
字号:
if ((x = malloc(strlen(n) + 3 + PAD)) == NULL) return NULL; x[0] = PATH_START; x[1] = '.'; strcpy(x + 2, n); *(t = x + 2 + (t - n)) = PATH_END; while (--t > x) if (*t == '/') *t = '.'; } strupper(x);#endif /* ?(VMS || TOPS20) */#if defined(OS2) || defined(WIN32) if ( !IsFileNameValid(x) ) ChangeNameForFAT(x);#endif /* !OS2 */ return x;}int check_dup()/* Sort the found list and remove duplicates. Return an error code in the ZE_ class. */{ struct flist far *f; /* steps through found linked list */ extent j; /* index for s */ struct flist far **s; /* sorted table */ /* sort found list, remove duplicates */ if (fcount) { if ((s = (struct flist far **)malloc( fcount * sizeof(struct flist far *))) == NULL) return ZE_MEM; for (j = 0, f = found; f != NULL; f = f->nxt) s[j++] = f; qsort((char *)s, fcount, sizeof(struct flist far *), fqcmp); for (j = fcount - 1; j > 0; j--) if (strcmp(s[j - 1]->name, s[j]->name) == 0) fexpel(s[j]); /* fexpel() changes fcount */ qsort((char *)s, fcount, sizeof(struct flist far *), fqcmpz); for (j = 1; j < fcount; j++) if (strcmp(s[j - 1]->zname, s[j]->zname) == 0) { warn("name in zip file repeated: ", s[j]->zname); warn(" first full name: ", s[j - 1]->name); warn(" second full name: ", s[j]->name); return ZE_PARMS; } free((voidp *)s); } return ZE_OK;}int filter(name) char *name; /* Scan the -i and -x lists for matches to the given name. Return true if the name must be included, false otherwise. Give precedence to -x over -i. */{ int n; int include = icount ? 0 : 1;#ifdef MATCH_LASTNAME_ONLY char *p = last(name); if (*p) name = p;#endif if (pcount == 0) return 1; for (n = 0; n < pcount; n++) { if (MATCH(patterns[n].zname, name)) { if (patterns[n].select == 'x') return 0; include = 1; } } return include;}local int newname(n, isdir)char *n; /* name to add (or exclude) */int isdir; /* true for a directory *//* Add (or exclude) the name of an existing disk file. Return an error code in the ZE_ class. */{ char *m; struct flist far *f; /* where in found, or new found entry */ struct zlist far *z; /* where in zfiles (if found) */ int dosflag; /* Search for name in zip file. If there, mark it, else add to list of new names to do (or remove from that list). */ if ((m = ex2in(n, isdir, &dosflag)) == NULL) return ZE_MEM; /* Discard directory names with zip -rj */ if (*m == '\0') {#ifndef AMIGA/* A null string is a legitimate external directory name in AmigaDOS; also, * a command like "zip -r zipfile FOO:" produces an empty internal name. */ if (pathput) error("empty name without -j");#endif free((voidp *)m); return ZE_OK; } if ((z = zsearch(m)) != NULL) { z->mark = pcount ? filter(m) : 1; if (z->mark == 0) { free((voidp *)m); if (verbose) fprintf(mesg, "zip diagnostic: excluding %s\n", z->name); } else { free((voidp *)(z->name)); if ((z->name = malloc(strlen(n) + 1 + PAD)) == NULL) return ZE_MEM; strcpy(z->name, n);#ifdef FORCE_NEWNAME free((voidp *)(z->zname)); z->zname = m;#else /* Better keep the old name. Useful when updating on MSDOS a zip file * made on Unix. */ free((voidp *)m);#endif z->dosflag = dosflag; if (verbose) fprintf(mesg, "zip diagnostic: including %s\n", z->name); } if (n == label) { label = z->name; } } else if (pcount == 0 || filter(m)) { /* Check that we are not adding the zip file to itself. This * catches cases like "zip -m foo ../dir/foo.zip". */ struct stat statb; if (zipstate == -1) zipstate = strcmp(zipfile, "-") != 0 && stat(zipfile, &zipstatb) == 0; if (zipstate == 1 && (statb = zipstatb, stat(n, &statb) == 0 && zipstatb.st_mode == statb.st_mode && zipstatb.st_ino == statb.st_ino && zipstatb.st_dev == statb.st_dev && zipstatb.st_uid == statb.st_uid && zipstatb.st_gid == statb.st_gid && zipstatb.st_size == statb.st_size && zipstatb.st_mtime == statb.st_mtime && zipstatb.st_ctime == statb.st_ctime)) /* Don't compare a_time since we are reading the file */ return ZE_OK; /* allocate space and add to list */ if ((f = (struct flist far *)farmalloc(sizeof(struct flist))) == NULL || (f->name = malloc(strlen(n) + 1 + PAD)) == NULL) { if (f != NULL) farfree((voidp far *)f); return ZE_MEM; } strcpy(f->name, n); f->zname = m; f->dosflag = dosflag; *fnxt = f; f->lst = fnxt; f->nxt = NULL; fnxt = &f->nxt; fcount++; if (n == label) { label = f->name; } } return ZE_OK;}int procname(n)char *n; /* name to process *//* Process a name or sh expression to operate on (or exclude). Return an error code in the ZE_ class. */{#if (!defined(VMS) && !defined(TOPS20)) char *a; /* path and name for recursion */#endif dstrm *d; /* directory stream from opend() */ char *e; /* pointer to name from readd() */ int m; /* matched flag */ char *p; /* path for recursion */ struct stat s; /* result of stat() */ struct zlist far *z; /* steps through zfiles list */ if (strcmp(n, "-") == 0) /* if compressing stdin */ return newname(n, 0); else if (#ifdef S_IFLNK /* if symbolic links exist ... */ linkput ? lstat(n, &s) :#endif /* S_IFLNK */ SSTAT(n, &s)#if defined(__TURBOC__) || defined(VMS) || defined(__WATCOMC__) /* For these 3 compilers, stat() succeeds on wild card names! */ || isshexp(n)#endif ) { /* Not a file or directory--search for shell expression in zip file */ p = ex2in(n, 0, (int *)NULL); /* shouldn't affect matching chars */ m = 1; for (z = zfiles; z != NULL; z = z->nxt) { if (MATCH(p, z->zname)) { z->mark = pcount ? filter(z->zname) : 1; if (verbose) fprintf(mesg, "zip diagnostic: %scluding %s\n", z->mark ? "in" : "ex", z->name); m = 0; } } free((voidp *)p); return m ? ZE_MISS : ZE_OK; } /* Live name--use if file, recurse if directory */#ifdef __human68k__ _toslash(n);#endif#ifdef MSDOS for (p = n; *p; p++) /* use / consistently */ if (*p == '\\') *p = '/';#endif /* MSDOS */ if ((s.st_mode & S_IFDIR) == 0) { /* add or remove name of file */ if ((m = newname(n, 0)) != ZE_OK) return m; } else {#if defined(VMS) || defined(TOPS20) if (dirnames && (m = newname(n, 1)) != ZE_OK) { return m; } /* recurse into directory */ if (recurse && (d = opend(n)) != NULL) { while ((e = readd(d)) != NULL) { if ((m = procname(e)) != ZE_OK) /* recurse on name */ { closed(d); return m; } } closed(d); }#else /* (VMS || TOPS20) */ /* Add trailing / to the directory name */ if ((p = malloc(strlen(n)+2)) == NULL) return ZE_MEM; if (strcmp(n, ".") == 0) { *p = 0; /* avoid "./" prefix and do not create zip entry */ } else { strcpy(p, n); a = p + strlen(p);#ifdef AMIGA if (*p && a[-1] != '/' && a[-1] != ':')#else if (a[-1] != '/')#endif strcpy(a, "/"); if (dirnames && (m = newname(p, 1)) != ZE_OK) { free((voidp *)p); return m; } } /* recurse into directory */ if (recurse && (d = opend(n)) != NULL) { while ((e = readd(d)) != NULL) { if (strcmp(e, ".") && strcmp(e, "..")) { if ((a = malloc(strlen(p) + strlen(e) + 1)) == NULL) { free((voidp *)p); closed(d); return ZE_MEM; } strcat(strcpy(a, p), e); if ((m = procname(a)) != ZE_OK) /* recurse on name */ { if (m == ZE_MISS) warn("name not matched: ", a); else err(m, a); } free((voidp *)a); } } free((voidp *)p); closed(d); }#endif /* ? (VMS || TOPS20) */ } /* (s.st_mode & S_IFDIR) == 0) */ return ZE_OK;}#if !defined(CRAY) && !defined(__TURBOC__) && !defined(OS2) /* and ... */#if !defined( __GO32__)local int cmptime(p, q)struct tm *p, *q; /* times to compare *//* Return negative if time p is before time q, positive if after, and zero if the same */{ int r; /* temporary variable */ if (p == NULL) return -1; else if ((r = p->tm_year - q->tm_year) != 0) return r; else if ((r = p->tm_mon - q->tm_mon) != 0) return r; else if ((r = p->tm_mday - q->tm_mday) != 0) return r; else if ((r = p->tm_hour - q->tm_hour) != 0) return r; else if ((r = p->tm_min - q->tm_min) != 0) return r; else return p->tm_sec - q->tm_sec;}local time_t invlocal(t)struct tm *t; /* time to convert *//* Find inverse of localtime() using bisection. This routine assumes that time_t is an integer type, either signed or unsigned. The expectation is that sometime before the year 2038, time_t will be made a 64-bit integer, and this routine will still work. */{ time_t i; /* midpoint of current root range */ time_t l; /* lower end of root range */ time_t u; /* upper end of root range */ /* Bracket the root [0,largest time_t]. Note: if time_t is a 32-bit signed integer, then the upper bound is GMT 1/19/2038 03:14:07, after which all the Unix systems in the world come to a grinding halt. Either that, or all those systems will suddenly find themselves transported to December of 1901 ... */ l = 0; u = 1; while (u < (u << 1)) u = (u << 1) + 1; /* Find the root */ while (u - l > 1) { i = l + ((u - l) >> 1); if (cmptime(localtime(&i), t) <= 0) l = i; else u = i; } return l;}#endif#endifvoid stamp(f, d)char *f; /* name of file to change */ulg d; /* dos-style time to change it to *//* Set last updated and accessed time of file f to the DOS time d. */{#if defined(MACOS) warn("timestamp not implemented yet", "");#else#ifdef __TURBOC__ int h; /* file handle */ if ((h = open(f, 0)) != -1) {#ifdef ATARI_ST d = ( d >> 16 ) | ( d << 16 );#endif setftime(h, (struct ftime *)&d); close(h); }#else /* !__TURBOC__ */#ifdef VMS int tm_sec, tm_min, tm_hour, tm_mday, tm_mon, tm_year; char timbuf[24]; static char *month[] = {"JAN", "FEB", "MAR", "APR", "MAY", "JUN", "JUL", "AUG", "SEP", "OCT", "NOV", "DEC"}; struct VMStimbuf { char *actime; /* VMS revision date, ASCII format */ char *modtime; /* VMS creation date, ASCII format */ } ascii_times = {timbuf, timbuf}; /* Convert DOS time to ASCII format for VMSmunch */ tm_sec = (int)(d << 1) & 0x3e; tm_min = (int)(d >> 5) & 0x3f; tm_hour = (int)(d >> 11) & 0x1f; tm_mday = (int)(d >> 16) & 0x1f; tm_mon = ((int)(d >> 21) & 0xf) - 1; tm_year = ((int)(d >> 25) & 0x7f) + 1980; sprintf(timbuf, "%02d-%3s-%04d %02d:%02d:%02d.00", tm_mday, month[tm_mon], tm_year, tm_hour, tm_min, tm_sec); /* Set updated and accessed times of f */ if (VMSmunch(f, SET_TIMES, &ascii_times) != RMS$_NMF) warn("can't set zipfile time: ", f);#else /* !VMS */#ifdef OS2 SetFileTime(f, d);#else /* !OS2 */ struct tm t; /* argument for mktime() or invlocal() */#if defined(WIN32) || defined(sgi) struct utimbuf u; /* argument for utime() */#else time_t u[2]; /* argument for utime() */#endif#ifndef __GO32__ extern time_t mktime OF((struct tm *));#endif /* Convert DOS time to time_t format in u[0] and u[1] */ t.tm_sec = (int)(d << 1) & 0x3e; t.tm_min = (int)(d >> 5) & 0x3f; t.tm_hour = (int)(d >> 11) & 0x1f; t.tm_mday = (int)(d >> 16) & 0x1f; t.tm_mon = ((int)(d >> 21) & 0xf) - 1; t.tm_year = ((int)(d >> 25) & 0x7f) + 80;#if defined(WIN32) || defined (sgi) u.actime = u.modtime = mktime(&t);#else# if defined(MSDOS) || defined(OS2) || defined(CRAY) /* mktime() is more reliable than invlocal() because the time range is * wider on MSDOS than on Unix; required for Cray because invlocal assumes * 32-bit ints */ u[0] = u[1] = mktime(&t);# else u[0] = u[1] = invlocal(&t);# endif#endif /* Set updated and accessed times of f */#if defined(WIN32) || defined(sgi) utime(f, &u);#else utime(f, u);#endif#endif /* ?OS2 */#endif /* ?VMS */#endif /* ?__TURBOC__ */#endif /* ?MACOS */}local void inctime(s)struct tm *s; /* time to increment in place *//* Increment the time structure *s by one second, return the result in place. */{ int y; /* temporary variable */ /* days in each month, except for February */ static int days[] = {31,0,31,30,31,30,31,31,30,31,30,31}; /* Set days in February from year (1900 is a leap year, 2000 is not) */ y = s->tm_year + 1900; days[1] = y % 4 == 0 && (y % 100 != 0 || y % 400 == 0) ? 29 : 28; /* Increment time with carry */ if (s->tm_sec != 59) s->tm_sec++; else if (s->tm_sec = 0, s->tm_min != 59) s->tm_min++; else if (s->tm_min = 0, s->tm_hour != 23) s->tm_hour++; else if (s->tm_hour = 0, s->tm_mday != days[s->tm_mon]) s->tm_mday++; else if (s->tm_mday = 1, s->tm_mon != 11) s->tm_mon++; else { s->tm_mon = 0; s->tm_year++; }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -