home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 9 Archive / 09-Archive.zip / unzip532.zip / cmsmvs / vmmvs.c < prev    next >
C/C++ Source or Header  |  1997-10-21  |  15KB  |  574 lines

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