⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 fileio.c

📁 给出了 zip 压缩算法的完整实现过程。
💻 C
📖 第 1 页 / 共 2 页
字号:
int h;                  /* hour */int m;                  /* minute */int s;                  /* second *//* Convert the date y/n/d and time h:m:s to a four byte DOS date and   time (date in high two bytes, time in low two bytes allowing magnitude   comparison). */{  return y < 1980 ? DOSTIME_MINIMUM /* dostime(1980, 1, 1, 0, 0, 0) */ :        (((ulg)y - 1980) << 25) | ((ulg)n << 21) | ((ulg)d << 16) |        ((ulg)h << 11) | ((ulg)m << 5) | ((ulg)s >> 1);}ulg unix2dostime(t)time_t *t;              /* unix time to convert *//* Return the Unix time t in DOS format, rounded up to the next two   second boundary. */{  time_t t_even;  struct tm *s;         /* result of localtime() */  t_even = (time_t)(((unsigned long)(*t) + 1) & (~1));                                /* Round up to even seconds. */  s = localtime(&t_even);       /* Use local time since MSDOS does. */  if (s == (struct tm *)NULL) {      /* time conversion error; use current time as emergency value         (assuming that localtime() does at least accept this value!) */      t_even = (time_t)(((unsigned long)time(NULL) + 1) & (~1));      s = localtime(&t_even);  }  return dostime(s->tm_year + 1900, s->tm_mon + 1, s->tm_mday,                 s->tm_hour, s->tm_min, s->tm_sec);}int issymlnk(a)ulg a;                  /* Attributes returned by filetime() *//* Return true if the attributes are those of a symbolic link */{#ifndef QDOS#ifdef S_IFLNK#ifdef __human68k__  int *_dos_importlnenv(void);  if (_dos_importlnenv() == NULL)    return 0;#endif  return ((a >> 16) & S_IFMT) == S_IFLNK;#else /* !S_IFLNK */  return (int)a & 0;    /* avoid warning on unused parameter */#endif /* ?S_IFLNK */#else  return 0;#endif}#endif /* !UTIL */#if (!defined(UTIL) && !defined(ZP_NEED_GEN_D2U_TIME))   /* There is no need for dos2unixtime() in the ZipUtils' code. */#  define ZP_NEED_GEN_D2U_TIME#endif#if ((defined(OS2) || defined(VMS)) && defined(ZP_NEED_GEN_D2U_TIME))   /* OS/2 and VMS use a special solution to handle time-stams of files. */#  undef ZP_NEED_GEN_D2U_TIME#endif#if (defined(W32_STATROOT_FIX) && !defined(ZP_NEED_GEN_D2U_TIME))   /* The Win32 stat()-bandaid to fix stat'ing root directories needs    * dos2unixtime() to calculate the time-stamps. */#  define ZP_NEED_GEN_D2U_TIME#endif#ifdef ZP_NEED_GEN_D2U_TIMEtime_t dos2unixtime(dostime)ulg dostime;            /* DOS time to convert *//* Return the Unix time_t value (GMT/UTC time) for the DOS format (local) * time dostime, where dostime is a four byte value (date in most significant * word, time in least significant word), see dostime() function. */{  struct tm *t;         /* argument for mktime() */  ZCONST time_t clock = time(NULL);  t = localtime(&clock);  t->tm_isdst = -1;     /* let mktime() determine if DST is in effect */  /* Convert DOS time to UNIX time_t format */  t->tm_sec  = (((int)dostime) <<  1) & 0x3e;  t->tm_min  = (((int)dostime) >>  5) & 0x3f;  t->tm_hour = (((int)dostime) >> 11) & 0x1f;  t->tm_mday = (int)(dostime >> 16) & 0x1f;  t->tm_mon  = ((int)(dostime >> 21) & 0x0f) - 1;  t->tm_year = ((int)(dostime >> 25) & 0x7f) + 80;  return mktime(t);}#undef ZP_NEED_GEN_D2U_TIME#endif /* ZP_NEED_GEN_D2U_TIME */#ifndef MACOSint destroy(f)char *f;                /* file to delete *//* Delete the file *f, returning non-zero on failure. */{  return unlink(f);}int replace(d, s)char *d, *s;            /* destination and source file names *//* Replace file *d by file *s, removing the old *s.  Return an error code   in the ZE_ class. This function need not preserve the file attributes,   this will be done by setfileattr() later. */{  struct stat t;        /* results of stat() */#if defined(CMS_MVS)  /* cmsmvs.h defines FOPW_TEMP as memory(hiperspace).  Since memory is   * lost at end of run, always do copy instead of rename.   */  int copy = 1;#else  int copy = 0;#endif  int d_exists;#if defined(VMS) || defined(CMS_MVS)  /* stat() is broken on VMS remote files (accessed through Decnet).   * This patch allows creation of remote zip files, but is not sufficient   * to update them or compress remote files */  unlink(d);#else /* !(VMS || CMS_MVS) */  d_exists = (LSTAT(d, &t) == 0);  if (d_exists)  {    /*     * respect existing soft and hard links!     */    if (t.st_nlink > 1# ifdef S_IFLNK        || (t.st_mode & S_IFMT) == S_IFLNK# endif        )       copy = 1;    else if (unlink(d))       return ZE_CREAT;                 /* Can't erase zip file--give up */  }#endif /* ?(VMS || CMS_MVS) */#ifndef CMS_MVS  if (!copy) {      if (rename(s, d)) {               /* Just move s on top of d */          copy = 1;                     /* failed ? */#if !defined(VMS) && !defined(ATARI) && !defined(AZTEC_C)#if !defined(CMS_MVS) && !defined(RISCOS) && !defined(QDOS)    /* For VMS, ATARI, AMIGA Aztec, VM_CMS, MVS, RISCOS,       always assume that failure is EXDEV */          if (errno != EXDEV#  ifdef THEOS           && errno != EEXIST#  else#    ifdef ENOTSAM           && errno != ENOTSAM /* Used at least on Turbo C */#    endif#  endif              ) return ZE_CREAT;#endif /* !CMS_MVS && !RISCOS */#endif /* !VMS && !ATARI && !AZTEC_C */      }  }#endif /* !CMS_MVS */  if (copy) {    FILE *f, *g;        /* source and destination files */    int r;              /* temporary variable */#ifdef RISCOS    if (SWI_OS_FSControl_26(s,d,0xA1)!=NULL) {#endif    if ((f = fopen(s, FOPR)) == NULL) {      fprintf(stderr," replace: can't open %s\n", s);      return ZE_TEMP;    }    if ((g = fopen(d, FOPW)) == NULL)    {      fclose(f);      return ZE_CREAT;    }    r = fcopy(f, g, (ulg)-1L);    fclose(f);    if (fclose(g) || r != ZE_OK)    {      unlink(d);      return r ? (r == ZE_TEMP ? ZE_WRITE : r) : ZE_WRITE;    }    unlink(s);#ifdef RISCOS    }#endif  }  return ZE_OK;}#endif /* !MACOS */int getfileattr(f)char *f;                /* file path *//* Return the file attributes for file f or 0 if failure */{#ifdef __human68k__  struct _filbuf buf;  return _dos_files(&buf, f, 0xff) < 0 ? 0x20 : buf.atr;#else  struct stat s;  return SSTAT(f, &s) == 0 ? (int) s.st_mode : 0;#endif}int setfileattr(f, a)char *f;                /* file path */int a;                  /* attributes returned by getfileattr() *//* Give the file f the attributes a, return non-zero on failure */{#if defined(TOPS20) || defined (CMS_MVS)  return 0;#else#ifdef __human68k__  return _dos_chmod(f, a) < 0 ? -1 : 0;#else  return chmod(f, a);#endif#endif}#ifndef VMS /* VMS-specific function is in VMS.C. */char *tempname(zip)char *zip;              /* path name of zip file to generate temp name for *//* Return a temporary file name in its own malloc'ed space, using tempath. */{  char *t = zip;   /* malloc'ed space for name (use zip to avoid warning) */#ifdef CMS_MVS  if ((t = malloc(strlen(tempath)+L_tmpnam+2)) == NULL)    return NULL;#  ifdef VM_CMS  tmpnam(t);  /* Remove filemode and replace with tempath, if any. */  /* Otherwise A-disk is used by default */  *(strrchr(t, ' ')+1) = '\0';  if (tempath!=NULL)     strcat(t, tempath);  return t;#  else   /* !VM_CMS */  /* For MVS */  tmpnam(t);  if (tempath != NULL)  {    int l1 = strlen(t);    char *dot;    if (*t == '\'' && *(t+l1-1) == '\'' && (dot = strchr(t, '.')))    {      /* MVS and not OE.  tmpnam() returns quoted string of 5 qualifiers.       * First is HLQ, rest are timestamps.  User can only replace HLQ.       */      int l2 = strlen(tempath);      if (strchr(tempath, '.') || l2 < 1 || l2 > 8)        ziperr(ZE_PARMS, "On MVS and not OE, tempath (-b) can only be HLQ");      memmove(t+1+l2, dot, l1+1-(dot-t));  /* shift dot ready for new hlq */      memcpy(t+1, tempath, l2);            /* insert new hlq */    }    else    {      /* MVS and probably OE.  tmpnam() returns filename based on TMPDIR,       * no point in even attempting to change it.  User should modify TMPDIR       * instead.       */      zipwarn("MVS, assumed to be OE, change TMPDIR instead of option -b: ",              tempath);    }  }  return t;#  endif  /* !VM_CMS */#else /* !CMS_MVS */#ifdef TANDEM  char cur_subvol [FILENAME_MAX];  char temp_subvol [FILENAME_MAX];  char *zptr;  char *ptr;  char *cptr = &cur_subvol[0];  char *tptr = &temp_subvol[0];  short err;  FILE *tempf;  int attempts;  t = (char *)malloc(NAMELEN); /* malloc here as you cannot free */                               /* tmpnam allocated storage later */  zptr = strrchr(zip, TANDEM_DELIMITER);  if (zptr != NULL) {    /* ZIP file specifies a Subvol so make temp file there so it can just       be renamed at end */    *tptr = *cptr = '\0';    strcat(cptr, getenv("DEFAULTS"));    strncat(tptr, zip, _min(FILENAME_MAX, (zptr - zip)) ); /* temp subvol */    strncat(t, zip, _min(NAMELEN, ((zptr - zip) + 1)) );   /* temp stem   */    err = chvol(tptr);    ptr = t + strlen(t);  /* point to end of stem */  }  else    ptr = t;  /* If two zips are running in same subvol then we can get contention problems     with the temporary filename.  As a work around we attempt to create     the file here, and if it already exists we get a new temporary name */  attempts = 0;  do {    attempts++;    tmpnam(ptr);  /* Add filename */    tempf = fopen(ptr, FOPW_TMP);    /* Attempt to create file */  } while (tempf == NULL && attempts < 100);  if (attempts >= 100) {    ziperr(ZE_TEMP, "Could not get unique temp file name");  }  fclose(tempf);  if (zptr != NULL) {    err = chvol(cptr);  /* Put ourself back to where we came in */  }  return t;#else /* !CMS_MVS && !TANDEM *//* * Do something with TMPDIR, TMP, TEMP ???? */  if (tempath != NULL)  {    if ((t = malloc(strlen(tempath)+12)) == NULL)      return NULL;    strcpy(t, tempath);#if (!defined(VMS) && !defined(TOPS20))#  ifdef MSDOS    {      char c = (char)lastchar(t);      if (c != '/' && c != ':' && c != '\\')        strcat(t, "/");    }#  else#    ifdef AMIGA    {      char c = (char)lastchar(t);      if (c != '/' && c != ':')        strcat(t, "/");    }#    else /* !AMIGA */#      ifdef RISCOS    if (lastchar(t) != '.')      strcat(t, ".");#      else /* !RISCOS */#        ifdef QDOS    if (lastchar(t) != '_')      strcat(t, "_");#        else    if (lastchar(t) != '/')      strcat(t, "/");#        endif /* ?QDOS */#      endif /* ?RISCOS */#    endif  /* ?AMIGA */#  endif /* ?MSDOS */#endif /* !VMS && !TOPS20 */  }  else  {    if ((t = malloc(12)) == NULL)      return NULL;    *t = 0;  }#ifdef NO_MKTEMP  {    char *p = t + strlen(t);    sprintf(p, "%08lx", (ulg)time(NULL));    return t;  }#else  strcat(t, "ziXXXXXX"); /* must use lowercase for Linux dos file system */  return mktemp(t);#endif /* NO_MKTEMP */#endif /* TANDEM */#endif /* CMS_MVS */}#endif /* !VMS */int fcopy(f, g, n)FILE *f, *g;            /* source and destination files */ulg n;                  /* number of bytes to copy or -1 for all *//* Copy n bytes from file *f to file *g, or until EOF if (long)n == -1.   Return an error code in the ZE_ class. */{  char *b;              /* malloc'ed buffer for copying */  extent k;             /* result of fread() */  ulg m;                /* bytes copied so far */  if ((b = malloc(CBSZ)) == NULL)    return ZE_MEM;  m = 0;  while (n == (ulg)(-1L) || m < n)  {    if ((k = fread(b, 1, n == (ulg)(-1) ?                   CBSZ : (n - m < CBSZ ? (extent)(n - m) : CBSZ), f)) == 0)    {      if (ferror(f))      {        free((zvoid *)b);        return ZE_READ;      }      else        break;    }    if (fwrite(b, 1, k, g) != k)    {      free((zvoid *)b);      fprintf(stderr," fcopy: write error\n");      return ZE_TEMP;    }    m += k;  }  free((zvoid *)b);  return ZE_OK;}#ifdef NO_RENAMEint rename(from, to)ZCONST char *from;ZCONST char *to;{    unlink(to);    if (link(from, to) == -1)        return -1;    if (unlink(from) == -1)        return -1;    return 0;}#endif /* NO_RENAME */#ifdef ZMEM/************************//*  Function memset()   *//************************//* * memset - for systems without it *  bill davidsen - March 1990 */char *memset(buf, init, len)register char *buf;     /* buffer loc */register int init;      /* initializer */register unsigned int len;   /* length of the buffer */{    char *start;    start = buf;    while (len--) *(buf++) = init;    return(start);}/************************//*  Function memcpy()   *//************************/char *memcpy(dst,src,len)             /* v2.0f */register char *dst, *src;register unsigned int len;{    char *start;    start = dst;    while (len--)        *dst++ = *src++;    return(start);}/************************//*  Function memcmp()   *//************************/intmemcmp(b1,b2,len)                     /* jpd@usl.edu -- 11/16/90 */register char *b1, *b2;register unsigned int len;{    if (len) do {       /* examine each byte (if any) */      if (*b1++ != *b2++)        return (*((uch *)b1-1) - *((uch *)b2-1));  /* exit when miscompare */    } while (--len);    return(0);          /* no miscompares, yield 0 result */}#endif  /* ZMEM */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -