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 + -
显示快捷键?