vmmvs.c
上传用户:andy_li
上传日期:2007-01-06
资源大小:1019k
文件大小:17k
源码类别:

压缩解压

开发平台:

MultiPlatform

  1. /*---------------------------------------------------------------------------
  2.   vmmvs.c (for both VM/CMS and MVS)
  3.   Contains:  vmmvs_open_infile()
  4.              open_outfile()
  5.              close_outfile()
  6.              close_infile()
  7.              getVMMVSexfield()
  8.              do_wild()
  9.              mapattr()
  10.              mapname()
  11.              checkdir()
  12.              check_for_newer()
  13.              stat()
  14.              version()
  15.   ---------------------------------------------------------------------------*/
  16. #define UNZIP_INTERNAL
  17. #include "unzip.h"
  18. /********************************/
  19. /* Function vmmvs_open_infile() */
  20. /********************************/
  21. FILE *vmmvs_open_infile(__G)
  22.    __GDEF
  23. {
  24.    FILE *fzip;
  25.    G.tempfn = NULL;
  26.    fzip = fopen(G.zipfn, FOPR);
  27. #if 0
  28.    /* Let's try it without the convert for a while -- RG Hartwig */
  29.    if ((fzip = fopen(G.zipfn,"rb,recfm=fb")) == NULL) {
  30.       size_t cnt;
  31.       char *buf;
  32.       FILE *in, *out;
  33.       if ((buf = (char *)malloc(32768)) == NULL) return NULL;
  34.       if ((G.tempfn = tmpnam(NULL)) == NULL) return NULL;
  35.       if ((in = fopen(G.zipfn,"rb")) != NULL &&
  36.           (out = fopen(G.tempfn,"wb,recfm=fb,lrecl=1")) != NULL) {
  37.          Trace((stdout,"Converting ZIP file to fixed record format...n"));
  38.          while (!feof(in)) {
  39.             cnt = fread(buf,1,32768,in);
  40.             if (cnt) fwrite(buf,1,cnt,out);
  41.          }
  42.       }
  43.       else {
  44.          free(buf);
  45.          fclose(out);
  46.          fclose(in);
  47.          return NULL;
  48.       }
  49.       free(buf);
  50.       fclose(out);
  51.       fclose(in);
  52.       fzip = fopen(G.tempfn,"rb,recfm=fb");
  53.       if (fzip == NULL) return NULL;
  54.       /* Update the G.ziplen value since it might have changed after
  55.          the reformatting copy. */
  56.       fseek(fzip,0L,SEEK_SET);
  57.       fseek(fzip,0L,SEEK_END);
  58.       G.ziplen = ftell(fzip);
  59.    }
  60. #endif
  61.    return fzip;
  62. }
  63. /***************************/
  64. /* Function open_outfile() */
  65. /***************************/
  66. int open_outfile(__G)           /* return 1 if fail */
  67.     __GDEF
  68. {
  69.     char type[100];
  70.     char *mode = NULL;
  71.     if (G.pInfo->textmode)
  72.         mode = FOPWT;
  73.     else if (G.lrec.extra_field_length > 0 && G.extra_field != NULL) {
  74.         unsigned lef_len = (unsigned)(G.lrec.extra_field_length);
  75.         uch *lef_buf = G.extra_field;
  76.         while (lef_len > EB_HEADSIZE) {
  77.             unsigned eb_id = makeword(&lef_buf[EB_ID]);
  78.             unsigned eb_dlen = makeword(&lef_buf[EB_LEN]);
  79.             if (eb_dlen > (lef_len - EB_HEADSIZE)) {
  80.                 /* Discovered some extra field inconsistency! */
  81.                 TTrace((stderr,
  82.                         "open_outfile: block length %u > rest lef_size %un",
  83.                         eb_dlen, lef_len - EB_HEADSIZE));
  84.                 break;
  85.             }
  86.             if ((eb_id == EF_VMCMS || eb_id == EF_MVS) &&
  87.                 (getVMMVSexfield(type, lef_buf, eb_dlen) > 0)) {
  88.                 mode = type;
  89.                 break;
  90.             }
  91.             /* Skip this extra field block */
  92.             lef_buf += (eb_dlen + EB_HEADSIZE);
  93.             lef_len -= (eb_dlen + EB_HEADSIZE);
  94.         }
  95.     }
  96.     if (mode == NULL) mode = FOPW;
  97.     Trace((stderr, "Output file='%s' opening with '%s'n", G.filename, mode));
  98.     if ((G.outfile = fopen(G.filename, mode)) == NULL) {
  99.         Info(slide, 0x401, ((char *)slide, "nerror:  cannot create %sn",
  100.              G.filename));
  101.         Trace((stderr, "error %d: '%s'n", errno, strerror(errno)));
  102.         return 1;
  103.     }
  104.     return 0;
  105. } /* end function open_outfile() */
  106. /****************************/
  107. /* Function close_outfile() */
  108. /****************************/
  109. void close_outfile(__G)
  110.    __GDEF
  111. {
  112.    fclose(G.outfile);
  113. } /* end function close_outfile() */
  114. /***************************/
  115. /* Function close_infile() */
  116. /***************************/
  117. void close_infile(__G)
  118.    __GDEF
  119. {
  120.    fclose(G.zipfd);
  121.    /* If we're working from a temp file, erase it now */
  122.    if (G.tempfn)
  123.       remove(G.tempfn);
  124. } /* end function close_infile() */
  125. /******************************/
  126. /* Function getVMMVSexfield() */
  127. /******************************/
  128. extent getVMMVSexfield(type, ef_block, datalen)
  129.     char *type;
  130.     uch *ef_block;
  131.     unsigned datalen;
  132. {
  133.     fldata_t *fdata = (fldata_t *) &ef_block[4];
  134.     if (datalen < sizeof(fldata_t))
  135.         return 0;
  136.     strcpy(type, "w");
  137.     strcat(type,  fdata->__openmode == __TEXT   ? ""
  138.                  :fdata->__openmode == __BINARY ? "b"
  139.                  :fdata->__openmode == __RECORD ? "b,type=record"
  140.                  :                                "");
  141.     strcat(type, ",recfm=");
  142.     strcat(type,  fdata->__recfmF? "F"
  143.                  :fdata->__recfmV? "V"
  144.                  :fdata->__recfmU? "U"
  145.                  :                 "?");
  146.     if (fdata->__recfmBlk) strcat(type, "B");
  147.     if (fdata->__recfmS)   strcat(type, "S");
  148.     if (fdata->__recfmASA) strcat(type, "A");
  149.     if (fdata->__recfmM)   strcat(type, "M");
  150.     sprintf(type+strlen(type), ",lrecl=%ld", fdata->__recfmV
  151.                                               ? fdata->__maxreclen+4
  152.                                               : fdata->__maxreclen);
  153. #ifdef VM_CMS
  154.     /* For CMS, use blocksize for FB files only */
  155.     if (fdata->__recfmBlk)
  156.        sprintf(type+strlen(type), ",blksize=%ld", fdata->__blksize);
  157. #else
  158.     /* For MVS, always use blocksize */
  159.     sprintf(type+strlen(type), ",blksize=%ld", fdata->__blksize);
  160. #endif
  161.     return strlen(type);
  162. } /* end function getVMMVSexfield() */
  163. #ifndef SFX
  164. /**********************/
  165. /* Function do_wild() */   /* for porting:  dir separator; match(ignore_case) */
  166. /**********************/
  167. char *do_wild(__G__ wld)
  168.     __GDEF
  169.     char *wld;             /* only used first time on a given dir */
  170. {
  171.     static int First = 0;
  172.     static char filename[256];
  173.     if (First == 0) {
  174.        First = 1;
  175.        strcpy( filename, wld );
  176.        return filename;
  177.     }
  178.     else
  179.        return (char *)NULL;
  180. } /* end function do_wild() */
  181. #endif /* !SFX */
  182. /************************/
  183. /*  Function mapattr()  */
  184. /************************/
  185. int mapattr(__G)
  186.      __GDEF
  187. {
  188.     return 0;
  189. }
  190. /************************/
  191. /*  Function mapname()  */
  192. /************************/
  193. int mapname(__G__ renamed)
  194.             /* returns: */
  195.             /* 0 (PK_COOL) if no error, */
  196.             /* 1 (PK_WARN) if caution (filename trunc), */
  197.             /* 2 (PK_ERR)  if warning (skip file because dir doesn't exist), */
  198.             /* 3 (PK_BADERR) if error (skip file), */
  199.             /* 10 if no memory (skip file) */
  200.             /* 78 (IZ_VOL_LABEL) if path was volume label (skip it) */
  201.     __GDEF
  202.     int renamed;
  203. {
  204.     char newname[FILNAMSIZ], *lbar;
  205. #ifdef MVS
  206.     char *pmember;
  207. #endif
  208.     int name_changed = 0;
  209.     if (G.pInfo->vollabel)
  210.         return IZ_VOL_LABEL;    /* can't set disk volume labels in CMS_MVS */
  211. #ifdef MVS
  212.     /* Remove bad characters for MVS from the filename */
  213.     while ((lbar = strpbrk(G.filename, "_+-")) != NULL) {
  214.        /* Must use memmove() here because data overlaps.  */
  215.        /* strcpy() gives undefined behavior in this case. */
  216.        memmove(lbar, lbar+1, strlen(lbar));
  217.        name_changed = 1;
  218.     }
  219. #endif
  220.     /* Remove bad characters for MVS/CMS from the filename */
  221.     while ((lbar = strpbrk(G.filename, "()")) != NULL) {
  222.        memmove(lbar, lbar+1, strlen(lbar));
  223.        name_changed = 1;
  224.     }
  225. #ifdef VM_CMS
  226.     if ((lbar = strrchr(G.filename, '/')) != NULL) {
  227.         strcpy(newname, lbar+1);
  228.         Trace((stderr, "File '%s' renamed to '%s'n", G.filename, newname));
  229.         strcpy(G.filename, newname);
  230.         name_changed = 1;
  231.     }
  232. #else /* MVS */
  233.     if ((pmember = strrchr(G.filename, '/')) == NULL)
  234.         pmember = G.filename;
  235.     else
  236.         pmember++;
  237.     /* search for extension in file name */
  238.     if ((lbar = strrchr(pmember, '.')) != NULL) {
  239.         *lbar++ = '';
  240.         strcpy(newname, pmember);
  241.         strcpy(pmember, lbar);
  242.         strcat(pmember, "(");
  243.         strcat(pmember, newname);
  244.         strcat(pmember, ")");
  245.     }
  246.     /* Remove all 'internal' dots '.', to prevent false consideration as
  247.      * MVS path delimiters! */
  248.     while ((lbar = strrchr(G.filename, '.')) != NULL) {
  249.         memmove(lbar, lbar+1, strlen(lbar));
  250.         name_changed = 1;
  251.     }
  252.     /* Finally, convert path delimiters from internal '/' to external '.' */
  253.     while ((lbar = strchr(G.filename, '/')) != NULL)
  254.         *lbar = '.';
  255. #endif /* ?VM_CMS */
  256. #ifndef MVS
  257.     if ((lbar = strchr(G.filename, '.')) == NULL) {
  258.         printf("WARNING: file '%s' has no extension - renamed to '%s.NONAME'n"
  259.               ,G.filename, G.filename);
  260.        strcat(G.filename, ".NONAME");
  261.        name_changed = 1;
  262.     }
  263. #endif
  264.     checkdir(__G__ G.filename, GETPATH);
  265.     return name_changed;
  266. } /* end function mapname() */
  267. int checkdir(__G__ pathcomp, flag)
  268.     __GDEF
  269.     char *pathcomp;
  270.     int flag;
  271. /*
  272.  * returns:  1 - (on APPEND_NAME) truncated filename
  273.  *           2 - path doesn't exist, not allowed to create
  274.  *           3 - path doesn't exist, tried to create and failed; or
  275.  *               path exists and is not a directory, but is supposed to be
  276.  *           4 - path is too long
  277.  *          10 - can't allocate memory for filename buffers
  278.  */
  279. {
  280.     static int rootlen = 0;     /* length of rootpath */
  281.     static char *rootpath;      /* user's "extract-to" directory */
  282. #   define FN_MASK   7
  283. #   define FUNCTION  (flag & FN_MASK)
  284. /*---------------------------------------------------------------------------
  285.     ROOT:  if appropriate, store the path in rootpath and create it if neces-
  286.     sary; else assume it's a zipfile member and return.  This path segment
  287.     gets used in extracting all members from every zipfile specified on the
  288.     command line.  Note that under OS/2 and MS-DOS, if a candidate extract-to
  289.     directory specification includes a drive letter (leading "x:"), it is
  290.     treated just as if it had a trailing '/'--that is, one directory level
  291.     will be created if the path doesn't exist, unless this is otherwise pro-
  292.     hibited (e.g., freshening).
  293.   ---------------------------------------------------------------------------*/
  294. #if (!defined(SFX) || defined(SFX_EXDIR))
  295.     if (FUNCTION == ROOT) {
  296.         Trace((stderr, "initializing root path to [%s]n", pathcomp));
  297.         if (pathcomp == (char *)NULL) {
  298.             rootlen = 0;
  299.         }
  300.         else if ((rootlen = strlen(pathcomp)) > 0) {
  301.             if ((rootpath = (char *)malloc(rootlen+1)) == NULL) {
  302.                 rootlen = 0;
  303.                 return 10;
  304.             }
  305.             strcpy(rootpath, pathcomp);
  306.             Trace((stderr, "rootpath now = [%s]n", rootpath));
  307.         }
  308.         return 0;
  309.     }
  310. #endif /* !SFX || SFX_EXDIR */
  311. /*---------------------------------------------------------------------------
  312.     GETPATH:  copy full path to the string pointed at by pathcomp, and free
  313.     buildpath.
  314.   ---------------------------------------------------------------------------*/
  315.     if (FUNCTION == GETPATH) {
  316.         if (rootlen > 0) {
  317. #ifdef VM_CMS                     /* put the exdir after the filename */
  318.            strcat(pathcomp,".");       /* used as minidisk to be save on  */
  319.            strcat(pathcomp,rootpath);
  320. #else /* MVS */
  321.            char newfilename[PATH_MAX];
  322.            char *start_fname;
  323.            strcpy(newfilename,rootpath);
  324.            if (strchr(pathcomp,'(') == NULL) {
  325.               if ((start_fname = strrchr(pathcomp,'.')) == NULL) {
  326.                  start_fname = pathcomp;
  327.               }
  328.               else {
  329.                  *start_fname++ = '';
  330.                  strcat(newfilename, ".");
  331.                  strcat(newfilename, pathcomp);
  332.               }
  333.               strcat(newfilename,"(");
  334.               strcat(newfilename,start_fname);
  335.               strcat(newfilename,")");
  336.            }
  337.            else {
  338.               strcat(newfilename,".");
  339.               strcat(newfilename,pathcomp);
  340.            }
  341.            Trace((stdout, "new dataset : %sn", newfilename));
  342.            strcpy(pathcomp,newfilename);
  343. #endif /* ?VM_CMS */
  344.         }
  345.         return 0;
  346.     }
  347. /*---------------------------------------------------------------------------
  348.     END:  free rootpath, immediately prior to program exit.
  349.   ---------------------------------------------------------------------------*/
  350.     if (FUNCTION == END) {
  351.         Trace((stderr, "freeing rootpathn"));
  352.         if (rootlen > 0) {
  353.             free(rootpath);
  354.             rootlen = 0;
  355.         }
  356.         return 0;
  357.     }
  358.     return 99;  /* should never reach */
  359. } /* end function checkdir() */
  360. /******************************/
  361. /* Function check_for_newer() */  /* used for overwriting/freshening/updating */
  362. /******************************/
  363. int check_for_newer(__G__ filename)  /* return 1 if existing file is newer */
  364.     __GDEF                           /*  or equal; 0 if older; -1 if doesn't */
  365.     char *filename;                  /*  exist yet */
  366. {
  367.     FILE *stream;
  368.     if ((stream = fopen(filename, FOPR)) != NULL) {
  369.        fclose(stream);
  370.        /* File exists, assume it is "newer" than archive entry. */
  371.        return EXISTS_AND_NEWER;
  372.     }
  373.     /* File does not exist. */
  374.     return DOES_NOT_EXIST;
  375. } /* end function check_for_newer() */
  376. /*********************/
  377. /*  Function stat()  */
  378. /*********************/
  379. int stat(const char *path, struct stat *buf)
  380. {
  381.    FILE *fp;
  382.    char fname[PATH_MAX];
  383.    time_t ltime;
  384.    if ((fp = fopen(path, FOPR)) != NULL) {
  385.       fldata_t fdata;
  386.       if (fldata( fp, fname, &fdata ) == 0) {
  387.          buf->st_dev  = fdata.__device;
  388.          buf->st_mode = *(short *)(&fdata);
  389.       }
  390.       /* Determine file size by seeking to EOF */
  391.       fseek(fp,0L,SEEK_END);
  392.       buf->st_size = ftell(fp);
  393.       fclose(fp);
  394.       /* set time fields in stat buf to current time. */
  395.       time(&ltime);
  396.       buf->st_atime =
  397.       buf->st_mtime =
  398.       buf->st_ctime = ltime;
  399.       /* File exists, return success */
  400.       return 0;
  401.    }
  402.    return 1;
  403. }
  404. #ifdef STAND_ALONE
  405. /***************************/
  406. /*  Function main_vmmvs()  */
  407. /***************************/
  408. /* This function is called as main() to parse arguments                */
  409. /* into argc and argv.  This is required for stand-alone               */
  410. /* execution.  This calls the "real" main() when done.                 */
  411. int MAIN_VMMVS(void)
  412.    {
  413.     int  argc=0;
  414.     char *argv[50];
  415.     int  iArgLen;
  416.     char argstr[256];
  417.     char **pEPLIST, *pCmdStart, *pArgStart, *pArgEnd;
  418.    /* Get address of extended parameter list from S/370 Register 0 */
  419.    pEPLIST = (char **)__xregs(0);
  420.    /* Null-terminate the argument string */
  421.    pCmdStart = *(pEPLIST+0);
  422.    pArgStart = *(pEPLIST+1);
  423.    pArgEnd   = *(pEPLIST+2);
  424.    iArgLen   = pArgEnd - pCmdStart + 1;
  425.    /* Make a copy of the command string */
  426.    memcpy(argstr, pCmdStart, iArgLen);
  427.    argstr[iArgLen] = '';  /* Null-terminate */
  428.    /* Store first token (cmd) */
  429.    argv[argc++] = strtok(argstr, " ");
  430.    /* Store the rest (args) */
  431.    while (argv[argc-1])
  432.       argv[argc++] = strtok(NULL, " ");
  433.    argc--;  /* Back off last NULL entry */
  434.    /* Call "real" main() function */
  435.    return MAIN(argc, argv);
  436. }
  437. #endif  /* STAND_ALONE */
  438. #ifndef SFX
  439. /************************/
  440. /*  Function version()  */
  441. /************************/
  442. void version(__G)
  443.     __GDEF
  444. {
  445.     int len;
  446.     char liblvlmsg [50+1];
  447.     char *compiler = "?";
  448.     char *platform = "?";
  449.     char complevel[64];
  450.     /* Map the runtime library level information */
  451.     union {
  452.        unsigned int iVRM;
  453.        struct {
  454.           unsigned int pd:4;    /* Product designation */
  455.           unsigned int vv:4;    /* Version             */
  456.           unsigned int rr:8;    /* Release             */
  457.           unsigned int mm:16;   /* Modification level  */
  458.        } xVRM;
  459.     } VRM;
  460.     /* Break down the runtime library level */
  461.     VRM.iVRM = __librel();
  462.     sprintf(liblvlmsg, "Using runtime library level %s V%dR%dM%d",
  463.             (VRM.xVRM.pd==1 ? "LE" : "CE"),
  464.             VRM.xVRM.vv, VRM.xVRM.rr, VRM.xVRM.mm);
  465.     /* Note:  LE = Language Environment, CE = Common Env. (C/370). */
  466.     /* This refers ONLY to the current runtimes, not the compiler. */
  467. #ifdef VM_CMS
  468.     platform = "VM/CMS";
  469.     #ifdef __IBMC__
  470.        compiler = "IBM C";
  471.     #else
  472.        compiler  = "C/370";
  473.     #endif
  474. #endif
  475. #ifdef MVS
  476.     platform = "MVS";
  477.     #ifdef __IBMC__
  478.        compiler = "IBM C/C++";
  479.     #else
  480.        compiler = "C/370";
  481.     #endif
  482. #endif
  483. #ifdef __COMPILER_VER__
  484.     VRM.iVRM = __COMPILER_VER__;
  485.     sprintf(complevel," V%dR%dM%d",
  486.             VRM.xVRM.vv, VRM.xVRM.rr, VRM.xVRM.mm);
  487. #else
  488. #ifdef __IBMC__
  489.     sprintf(complevel," V%dR%d", __IBMC__ / 100, (__IBMC__ % 100)/10);
  490. #else
  491.     complevel[0] = '';
  492. #endif
  493. #endif
  494.     /* Output is in the form "Compiled with %s%s for %s%s%s%s." */
  495.     len = sprintf((char *)slide, LoadFarString(CompiledWith),
  496.     /* Add compiler name and level */
  497.     compiler, complevel,
  498.     /* Add compile environment */
  499.     platform,
  500.     /* Add timestamp */
  501. #ifdef __DATE__
  502.       " on " __DATE__
  503. #ifdef __TIME__
  504.       " at " __TIME__
  505. #endif
  506. #endif
  507.       ".n", "",
  508.       liblvlmsg
  509.     );
  510.     (*G.message)((zvoid *)&G, slide, (ulg)len, 0);
  511. } /* end function version() */
  512. #endif /* !SFX */