msdos.c
来自「infozip2.2源码」· C语言 代码 · 共 938 行 · 第 1/2 页
C
938 行
*pdosflag = dosflag; return n;}char *in2ex(n)char *n; /* internal file name *//* Convert the zip file name to an external file name, returning the malloc'ed string or NULL if not enough memory. */{ char *x; /* external file name */ if ((x = malloc(strlen(n) + 1 + PAD)) == NULL) return NULL; strcpy(x, n); return x;}void 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(__TURBOC__) || defined(__GO32__) int h; /* file handle */ if ((h = open(f, 0)) != -1) { setftime(h, (struct ftime *)&d); close(h); }#else /* !__TURBOC__ && !__GO32__ */ ztimbuf u; /* argument for utime() */ /* Convert DOS time to time_t format in u.actime and u.modtime */ u.actime = u.modtime = dos2unixtime(d); /* Set updated and accessed times of f */ utime(f, &u);#endif /* ?(__TURBOC__ || __GO32__) */}ulg filetime(f, a, n, t)char *f; /* name of file to get info on */ulg *a; /* return value: file attributes */long *n; /* return value: file size */iztimes *t; /* return value: access, modific. and creation times *//* If file *f does not exist, return 0. Else, return the file's last modified date and time as an MSDOS date and time. The date and time is returned in a long with the date most significant to allow unsigned integer comparison of absolute times. Also, if a is not a NULL pointer, store the file attributes there, with the high two bytes being the Unix attributes, and the low byte being a mapping of that to DOS attributes. If n is not NULL, store the file size there. If t is not NULL, the file's access, modification and creation times are stored there as UNIX time_t values. If f is "-", use standard input as the file. If f is a device, return a file size of -1 */{ struct stat s; /* results of stat() */ char name[FNMAX]; int len = strlen(f), isstdin = !strcmp(f, "-"); if (f == label) { if (a != NULL) *a = label_mode; if (n != NULL) *n = -2L; /* convention for a label name */ if (t != NULL) t->atime = t->mtime = t->ctime = label_utim; return label_time; }#if defined(__TURBOC__) /* Call tzset() to set timezone correctly (buggy older TC runtime libs) */ tzset();#endif /* __TURBOC__ */ strcpy(name, f); if (name[len - 1] == '/') name[len - 1] = '\0'; /* not all systems allow stat'ing a file with / appended */ if (isstdin) { if (fstat(fileno(stdin), &s) != 0) error("fstat(stdin)"); time((time_t *)&s.st_mtime); /* some fstat()s return time zero */ } else if (LSSTAT(name, &s) != 0) /* Accept about any file kind including directories * (stored with trailing / with -r option) */ return 0; if (a != NULL) *a = ((ulg)s.st_mode << 16) | (isstdin ? 0L : (ulg)GetFileMode(name)); if (n != NULL) *n = (s.st_mode & S_IFREG) != 0 ? s.st_size : -1L; if (t != NULL) { t->atime = s.st_atime; t->mtime = s.st_mtime; t->ctime = s.st_ctime; } return unix2dostime((time_t *)&s.st_mtime);}int deletedir(d)char *d; /* directory to delete *//* Delete the directory *d if it is empty, do nothing otherwise. Return the result of rmdir(), delete(), or system(). */{ return rmdir(d);}int set_extra_field(z, z_utim) struct zlist far *z; iztimes *z_utim; /* create extra field and change z->att if desired */{#ifdef USE_EF_UT_TIME if ((z->extra = (char *)malloc(EB_HEADSIZE+EB_UT_LEN(1))) == NULL) return ZE_MEM; z->extra[0] = 'U'; z->extra[1] = 'T'; z->extra[2] = EB_UT_LEN(1); /* length of data part of e.f. */ z->extra[3] = 0; z->extra[4] = EB_UT_FL_MTIME; z->extra[5] = (char)(z_utim->mtime); z->extra[6] = (char)(z_utim->mtime >> 8); z->extra[7] = (char)(z_utim->mtime >> 16); z->extra[8] = (char)(z_utim->mtime >> 24); z->cext = z->ext = (EB_HEADSIZE+EB_UT_LEN(1)); z->cextra = z->extra; return ZE_OK;#else /* !USE_EF_UT_TIME */ return (int)(z-z);#endif /* ?USE_EF_UT_TIME */}#ifdef MY_ZCALLOC /* Special zcalloc function for MEMORY16 (MSDOS/OS2) */#if defined(__TURBOC__) && !defined(OS2)/* Small and medium model are for now limited to near allocation with * reduced MAX_WBITS and MAX_MEM_LEVEL *//* Turbo C malloc() does not allow dynamic allocation of 64K bytes * and farmalloc(64K) returns a pointer with an offset of 8, so we * must fix the pointer. Warning: the pointer must be put back to its * original form in order to free it, use zcfree(). */#define MAX_PTR 10/* 10*64K = 640K */local int next_ptr = 0;typedef struct ptr_table_s { zvoid far *org_ptr; zvoid far *new_ptr;} ptr_table;local ptr_table table[MAX_PTR];/* This table is used to remember the original form of pointers * to large buffers (64K). Such pointers are normalized with a zero offset. * Since MSDOS is not a preemptive multitasking OS, this table is not * protected from concurrent access. This hack doesn't work anyway on * a protected system like OS/2. Use Microsoft C instead. */zvoid far *zcalloc (unsigned items, unsigned size){ zvoid far *buf; ulg bsize = (ulg)items*size; if (bsize < (65536L-16L)) { buf = farmalloc(bsize); if (*(ush*)&buf != 0) return buf; } else { buf = farmalloc(bsize + 16L); } if (buf == NULL || next_ptr >= MAX_PTR) return NULL; table[next_ptr].org_ptr = buf; /* Normalize the pointer to seg:0 */ *((ush*)&buf+1) += ((ush)((uch*)buf-NULL) + 15) >> 4; *(ush*)&buf = 0; table[next_ptr++].new_ptr = buf; return buf;}zvoid zcfree (zvoid far *ptr){ int n; if (*(ush*)&ptr != 0) { /* object < 64K */ farfree(ptr); return; } /* Find the original pointer */ for (n = next_ptr - 1; n >= 0; n--) { if (ptr != table[n].new_ptr) continue; farfree(table[n].org_ptr); while (++n < next_ptr) { table[n-1] = table[n]; } next_ptr--; return; } ziperr(ZE_MEM, "zcfree: ptr not found");}#endif /* __TURBOC__ */#if defined(MSC) || defined(__WATCOMC__)#if (!defined(_MSC_VER) || (_MSC_VER < 700))# define _halloc halloc# define _hfree hfree#endifzvoid far *zcalloc (unsigned items, unsigned size){ return (zvoid far *)_halloc((long)items, size);}zvoid zcfree (zvoid far *ptr){ _hfree((void huge *)ptr);}#endif /* MSC || __WATCOMC__ */#endif /* MY_ZCALLOC */#if (defined(__WATCOMC__) && defined(ASMV) && !defined(__386__))/* This is a hack to connect "call _exit" in match.asm to exit() */#pragma aux xit "_exit" parm caller []void xit(void){ exit(20);}#endif#endif /* !UTIL */#ifndef WINDLL/******************************//* Function version_local() *//******************************/static ZCONST char CompiledWith[] = "Compiled with %s%s for %s%s%s%s.\n\n"; /* At module level to keep Turbo C++ 1.0 happy !! */void version_local(){#if defined(__DJGPP__) || defined(__WATCOMC__) || \ (defined(_MSC_VER) && (_MSC_VER != 800)) char buf[80];#endif printf(CompiledWith,#ifdef __GNUC__# if defined(__DJGPP__) (sprintf(buf, "djgpp v%d / gcc ", __DJGPP__), buf),# elif defined(__GO32__) "djgpp v1.x / gcc ",# elif defined(__EMX__) /* ...so is __EMX__ (double sigh) */ "emx+gcc ",# else "gcc ",# endif __VERSION__,#elif defined(__WATCOMC__)# if (__WATCOMC__ % 10 > 0)/* We do this silly test because __WATCOMC__ gives two digits for the *//* minor version, but Watcom packaging prefers to show only one digit. */ (sprintf(buf, "Watcom C/C++ %d.%02d", __WATCOMC__ / 100, __WATCOMC__ % 100), buf), "",# else (sprintf(buf, "Watcom C/C++ %d.%d", __WATCOMC__ / 100, (__WATCOMC__ % 100) / 10), buf), "",# endif#elif defined(__TURBOC__)# ifdef __BORLANDC__ "Borland C++",# if (__BORLANDC__ < 0x0200) " 1.0",# elif (__BORLANDC__ == 0x0200) /* James: __TURBOC__ = 0x0297 */ " 2.0",# elif (__BORLANDC__ == 0x0400) " 3.0",# elif (__BORLANDC__ == 0x0410) /* __BCPLUSPLUS__ = 0x0310 */ " 3.1",# elif (__BORLANDC__ == 0x0452) /* __BCPLUSPLUS__ = 0x0320 */ " 4.0 or 4.02",# elif (__BORLANDC__ == 0x0460) /* __BCPLUSPLUS__ = 0x0340 */ " 4.5",# elif (__BORLANDC__ == 0x0500) /* __TURBOC__ = 0x0500 */ " 5.0",# else " later than 5.0",# endif# else "Turbo C",# if (__TURBOC__ > 0x0401) "++ later than 3.0"# elif (__TURBOC__ == 0x0401) /* Kevin: 3.0 -> 0x0401 */ "++ 3.0",# elif (__TURBOC__ == 0x0295) /* [661] vfy'd by Kevin */ "++ 1.0",# elif ((__TURBOC__ >= 0x018d) && (__TURBOC__ <= 0x0200)) /* James: 0x0200 */ " 2.0",# elif (__TURBOC__ > 0x0100) " 1.5", /* James: 0x0105? */# else " 1.0", /* James: 0x0100 */# endif# endif#elif defined(MSC) "Microsoft C ",# ifdef _MSC_VER# if (_MSC_VER == 800) "(Visual C++ v1.1)",# elif (_MSC_VER == 850) "(Windows NT v3.5 SDK)",# elif (_MSC_VER == 900) "(Visual C++ v2.0/v2.1)",# elif (_MSC_VER > 900) (sprintf(buf2, "(Visual C++ v%d.%d)", _MSC_VER/100 - 6, _MSC_VER%100/10), buf2),# else (sprintf(buf, "%d.%02d", _MSC_VER/100, _MSC_VER%100), buf),# endif# else "5.1 or earlier",# endif#else "unknown compiler", "",#endif "MS-DOS",#if (defined(__GNUC__) || (defined(__WATCOMC__) && defined(__386__))) " (32-bit)",#elif defined(M_I86HM) || defined(__HUGE__) " (16-bit, huge)",#elif defined(M_I86LM) || defined(__LARGE__) " (16-bit, large)",#elif defined(M_I86MM) || defined(__MEDIUM__) " (16-bit, medium)",#elif defined(M_I86CM) || defined(__COMPACT__) " (16-bit, compact)",#elif defined(M_I86SM) || defined(__SMALL__) " (16-bit, small)",#elif defined(M_I86TM) || defined(__TINY__) " (16-bit, tiny)",#else " (16-bit)",#endif#ifdef __DATE__ " on ", __DATE__#else "", ""#endif );} /* end function version_local() */#endif /* !WINDLL */#if __DJGPP__ == 2int _is_executable (const char *p,int i,const char *q){ return 0;}#endif#if defined(_MSC_VER) && _MSC_VER == 700/* * ARGH. MSC 7.0 libraries think times are based on 1899 Dec 31 00:00, not * 1970 Jan 1 00:00. So we have to diddle time_t's appropriately: add * 70 years' worth of seconds for localtime() wrapper function; * (70*365 regular days + 17 leap days + 1 1899 day) * 86400 == * (25550 + 17 + 1) * 86400 == 2209075200 seconds. * Let time() and stat() return seconds since 1970 by using our own * _dtoxtime() which is the routine that is called by these two functions. */#ifdef UTIL# include <time.h>#endif#ifndef UTIL#undef localtimestruct tm *localtime(const time_t *);struct tm *msc7_localtime(const time_t *clock){ time_t t = *clock; t += 2209075200L; return localtime(&t);}#endif /* !UTIL */void __tzset(void);int _isindst(struct tm *);extern int _days[];/* Nonzero if `y' is a leap year, else zero. */#define leap(y) (((y) % 4 == 0 && (y) % 100 != 0) || (y) % 400 == 0)/* Number of leap years from 1970 to `y' (not including `y' itself). */#define nleap(y) (((y) - 1969) / 4 - ((y) - 1901) / 100 + ((y) - 1601) / 400)time_t _dtoxtime(year, month, mday, hour, min, sec)int year, month, mday, year, hour, min, sec;{ struct tm tm; time_t t; int days; days = _days[month - 1] + mday; year += 1980; if (leap(year) && month > 2) ++days; tm.tm_yday = days; tm.tm_mon = month - 1; tm.tm_year = year - 1900; tm.tm_hour = hour; __tzset(); days += 365 * (year - 1970) + nleap (year); t = 86400L * days + 3600L * hour + 60 * min + sec + _timezone; if (_daylight && _isindst(&tm)) t -= 3600; return t;}#endif /* _MSC_VER && _MSC_VER == 700 */#ifdef __WATCOMC__/* This papers over a bug in Watcom 10.6's standard library... sigh *//* Apparently it applies to both the DOS and Win32 stat()s. */int stat_bandaid(const char *path, struct stat *buf){ char newname[4]; if (!stat(path, buf)) return 0; else if (!strcmp(path, ".") || (path[0] && !strcmp(path + 1, ":."))) { strcpy(newname, path); newname[strlen(path) - 1] = '\\'; /* stat(".") fails for root! */ return stat(newname, buf); } else return -1;}#endif
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?