home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 9 Archive / 09-Archive.zip / unzip531.zip / cmsmvs / vmmvs.c < prev    next >
C/C++ Source or Header  |  1996-07-23  |  13KB  |  511 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.     if ((G.outfile = fopen(G.filename, mode)) == (FILE *)NULL) {
  102.         Info(slide, 0x401, ((char *)slide, "\nerror:  cannot create %s\n",
  103.              G.filename));
  104.         return 1;
  105.     }
  106.     return 0;
  107. } /* end function open_outfile() */
  108.  
  109.  
  110. /****************************/
  111. /* Function close_outfile() */
  112. /****************************/
  113.  
  114. void close_outfile(__G)
  115.    __GDEF
  116. {
  117.    fclose(G.outfile);
  118. } /* end function close_outfile() */
  119.  
  120.  
  121. /****************************/
  122. /* Function close_infile() */
  123. /****************************/
  124.  
  125. void close_infile(__G)
  126.    __GDEF
  127. {
  128.    fclose(G.zipfd);
  129.  
  130.    /* If we're working from a temp file, erase it now */
  131.    if (G.tempfn)
  132.       remove(G.tempfn);
  133.  
  134. } /* end function close_infile() */
  135.  
  136.  
  137.  
  138. /******************************/
  139. /* Function getVMMVSexfield() */
  140. /******************************/
  141.  
  142. extent getVMMVSexfield(type, ef_block, datalen)
  143.     char *type;
  144.     uch *ef_block;
  145.     unsigned datalen;
  146. {
  147.     fldata_t *fdata = (fldata_t *) &ef_block[4];
  148.  
  149.     if (datalen < sizeof(fldata_t))
  150.         return 0;
  151.  
  152.     strcpy(type, "w");
  153.     strcat(type,  fdata->__openmode == __TEXT   ? ""
  154.                  :fdata->__openmode == __BINARY ? "b"
  155.                  :fdata->__openmode == __RECORD ? "b,type=record"
  156.                  : "");
  157.     strcat(type, ",recfm=");
  158.     strcat(type,  fdata->__recfmF? "F"
  159.                  :fdata->__recfmV? "V"
  160.                  :fdata->__recfmU? "U"
  161.                  :                 "?");
  162.     if (fdata->__recfmBlk) strcat(type, "B");
  163.     if (fdata->__recfmS)   strcat(type, "S");
  164.     if (fdata->__recfmASA) strcat(type, "A");
  165.     if (fdata->__recfmM)   strcat(type, "M");
  166.     sprintf(type+strlen(type), ",lrecl=%ld", fdata->__recfmV
  167.                                               ? fdata->__maxreclen+4
  168.                                               : fdata->__maxreclen);
  169.     sprintf(type+strlen(type), ",blksize=%ld", fdata->__blksize);
  170.  
  171.     return strlen(type);
  172. } /* end function getVMMVSexfield() */
  173.  
  174.  
  175.  
  176. #ifndef SFX
  177.  
  178. /**********************/
  179. /* Function do_wild() */   /* for porting:  dir separator; match(ignore_case) */
  180. /**********************/
  181.  
  182. char *do_wild(__G__ wld)
  183.     __GDEF
  184.     char *wld;             /* only used first time on a given dir */
  185. {
  186.     static int First = 0;
  187.     static char filename[256];
  188.  
  189.     if (First == 0) {
  190.        First = 1;
  191.        strcpy( filename, wld );
  192.        return filename;
  193.     }
  194.     else
  195.        return (char *)NULL;
  196.  
  197. } /* end function do_wild() */
  198.  
  199. #endif /* !SFX */
  200.  
  201.  
  202.  
  203. /************************/
  204. /*  Function mapattr()  */
  205. /************************/
  206.  
  207. int mapattr(__G)
  208.      __GDEF
  209. {
  210.     return 0;
  211. }
  212.  
  213. /************************/
  214. /*  Function mapname()  */
  215. /************************/
  216.  
  217. int mapname(__G__ renamed)
  218.             /* returns: */
  219.             /* 0 (PK_COOL) if no error, */
  220.             /* 1 (PK_WARN) if caution (filename trunc), */
  221.             /* 2 (PK_ERR)  if warning (skip file because dir doesn't exist), */
  222.             /* 3 (PK_BADERR) if error (skip file), */
  223.             /* 10 if no memory (skip file) */
  224.     __GDEF
  225.     int renamed;
  226. {
  227.     char newname[68], *lbar;
  228. #ifdef MVS
  229.     char *pmember;
  230. #endif
  231.     int name_changed = 0;
  232.  
  233. #ifdef MVS
  234.     while ((lbar = strrchr(G.filename,'_')) != NULL) {
  235.        strcpy(lbar,(lbar)+1);
  236.        name_changed = 1;
  237.     }
  238.     /* '-' and '+' ARE valid chars for CMS.  --RGH  */
  239.     while ((lbar = strrchr(G.filename,'+')) != NULL) {
  240.        strcpy(lbar,(lbar)+1);
  241.        name_changed = 1;
  242.     }
  243.     while ((lbar = strrchr(G.filename,'-')) != NULL) {
  244.        strcpy(lbar,(lbar)+1);
  245.        name_changed = 1;
  246.     }
  247. #endif
  248.  
  249.     while ((lbar = strrchr(G.filename,'(')) != NULL) {
  250.        strcpy(lbar,(lbar)+1);
  251.        name_changed = 1;
  252.     }
  253.     while ((lbar = strrchr(G.filename,')')) != NULL) {
  254.        strcpy(lbar,(lbar)+1);
  255.        name_changed = 1;
  256.     }
  257.  
  258. #ifdef VM_CMS
  259.     if ((lbar = strrchr(G.filename,'/')) != NULL) {
  260.         strcpy((char *)newname,(char *)((lbar)+1));
  261.         printf("WARNING: file '%s' renamed as '%s'\n",G.filename,newname);
  262.         strcpy(G.filename,(char *)newname);
  263.         name_changed = 1;
  264.     }
  265. #else /* MVS */
  266.     if ((pmember = strrchr(G.filename,'/')) == NULL)
  267.         pmember = G.filename;
  268.     else
  269.         pmember++;
  270.  
  271.     /* search for extension in file name */
  272.     if ((lbar = strrchr(pmember,'.')) != NULL) {
  273.         *lbar++ = '\0';
  274.         strcpy(newname, pmember);
  275.         strcpy(pmember, lbar);
  276.         strcat(pmember, "(");
  277.         strcat(pmember, newname);
  278.         strcat(pmember, ")");
  279.     }
  280.  
  281.     /* Remove all 'internal' dots '.', to prevent false consideration as
  282.      * MVS path delimiters! */
  283.     while ((lbar = strrchr(G.filename,'.')) != NULL) {
  284.         strcpy(lbar,(lbar)+1);
  285.         name_changed = 1;
  286.     }
  287.  
  288.     /* Finally, convert path delimiters from internal '/' to external '.' */
  289.     while ((lbar = strchr(G.filename,'/')) != NULL)
  290.         *lbar = '.';
  291. #endif /* ?VM_CMS */
  292.  
  293. #ifndef MVS
  294.     if ((lbar = strchr(G.filename,'.')) == (char *)NULL) {
  295.         printf("WARNING: file '%s' has NO extension - renamed as '%s.NONAME'\n"\
  296.               ,G.filename,G.filename);
  297.        strcat(G.filename,".NONAME");
  298.        name_changed = 1;
  299.     }
  300. #endif
  301.     checkdir(__G__ G.filename, GETPATH);
  302.  
  303.     return name_changed;
  304.  
  305. } /* end function mapname() */
  306.  
  307.  
  308. int checkdir(__G__ pathcomp, flag)
  309.     __GDEF
  310.     char *pathcomp;
  311.     int flag;
  312. /*
  313.  * returns:  1 - (on APPEND_NAME) truncated filename
  314.  *           2 - path doesn't exist, not allowed to create
  315.  *           3 - path doesn't exist, tried to create and failed; or
  316.  *               path exists and is not a directory, but is supposed to be
  317.  *           4 - path is too long
  318.  *          10 - can't allocate memory for filename buffers
  319.  */
  320. {
  321.     static int rootlen = 0;      /* length of rootpath */
  322.     static char *rootpath;       /* user's "extract-to" directory */
  323.  
  324. #   define FN_MASK   7
  325. #   define FUNCTION  (flag & FN_MASK)
  326.  
  327. #if (!defined(SFX) || defined(SFX_EXDIR))
  328.     if (FUNCTION == ROOT) {
  329.         Trace((stderr, "initializing root path to [%s]\n", pathcomp));
  330.         if (pathcomp == (char *)NULL) {
  331.             rootlen = 0;
  332.         }
  333.         else if ((rootlen = strlen(pathcomp)) > 0) {
  334.             if ((rootpath = (char *)malloc(rootlen+1)) == NULL) {
  335.                 rootlen = 0;
  336.                 return 10;
  337.             }
  338.             strcpy(rootpath, pathcomp);
  339.             Trace((stderr, "rootpath now = [%s]\n", rootpath));
  340.         }
  341.         return 0;
  342.     }
  343. #endif /* !SFX || SFX_EXDIR */
  344.  
  345. /*---------------------------------------------------------------------------
  346.     GETPATH:  copy full path to the string pointed at by pathcomp, and free
  347.     buildpath.
  348.   ---------------------------------------------------------------------------*/
  349.  
  350.     if (FUNCTION == GETPATH) {
  351.         if (rootlen > 0) {
  352. #ifdef VM_CMS                     /* put the exdir after the filename */
  353.            strcat(pathcomp,".");       /* used as minidisk to be save on  */
  354.            strcat(pathcomp,rootpath);
  355. #else /* MVS */
  356.            char newfilename[PATH_MAX];
  357.            char *start_fname;
  358.  
  359.            strcpy(newfilename,rootpath);
  360.            if (strchr(pathcomp,'(') == NULL) {
  361.               if ((start_fname = strrchr(pathcomp,'.')) == NULL) {
  362.                  start_fname = pathcomp;
  363.               }
  364.               else {
  365.                  *start_fname++ = '\0';
  366.                  strcat(newfilename, ".");
  367.                  strcat(newfilename, pathcomp);
  368.               }
  369.               strcat(newfilename,"(");
  370.               strcat(newfilename,start_fname);
  371.               strcat(newfilename,")");
  372.            }
  373.            else {
  374.               strcat(newfilename,".");
  375.               strcat(newfilename,pathcomp);
  376.            }
  377.            Trace((stdout, "new dataset : %s\n", newfilename));
  378.            strcpy(pathcomp,newfilename);
  379. #endif /* ?VM_CMS */
  380.         }
  381.         return 0;
  382.     }
  383.  
  384. /*---------------------------------------------------------------------------
  385.     END:  free rootpath, immediately prior to program exit.
  386.   ---------------------------------------------------------------------------*/
  387.  
  388.     if (FUNCTION == END) {
  389.         Trace((stderr, "freeing rootpath\n"));
  390.         if (rootlen > 0)
  391.             free(rootpath);
  392.         return 0;
  393.     }
  394.  
  395.     return 99;  /* should never reach */
  396.  
  397. } /* end function checkdir() */
  398.  
  399.  
  400. /******************************/
  401. /* Function check_for_newer() */  /* used for overwriting/freshening/updating */
  402. /******************************/
  403.  
  404. int check_for_newer(__G__ filename)  /* return 1 if existing file is newer */
  405.     __GDEF                           /*  or equal; 0 if older; -1 if doesn't */
  406.     char *filename;                  /*  exist yet */
  407. {
  408.     FILE *stream;
  409.  
  410.     if ((stream = fopen(filename, "r")) != (FILE *)NULL) {
  411.        fclose(stream);
  412.        /* File exists, assume it is "newer" than archive entry. */
  413.        return EXISTS_AND_NEWER;
  414.     }
  415.     /* File does not exist. */
  416.     return DOES_NOT_EXIST;
  417. } /* end function check_for_newer() */
  418.  
  419.  
  420. /*********************/
  421. /*  Function stat()  */
  422. /*********************/
  423.  
  424. int stat(const char *path, struct stat *buf)
  425. {
  426.    FILE *fp;
  427.    char fname[PATH_MAX];
  428.    time_t ltime;
  429.  
  430.    if ((fp = fopen(path, "rb")) != NULL) {
  431.       fldata_t fdata;
  432.       if (fldata( fp, fname, &fdata ) == 0) {
  433.          buf->st_dev  = fdata.__device;
  434.          buf->st_mode = *(short *)(&fdata);
  435.       }
  436.  
  437.       /* Determine file size by seeking to EOF */
  438.       fseek(fp,0L,SEEK_END);
  439.       buf->st_size = ftell(fp);
  440.       fclose(fp);
  441.  
  442.       /* set time fields in stat buf to current time. */
  443.       time(<ime);
  444.       buf->st_atime =
  445.       buf->st_mtime =
  446.       buf->st_ctime = ltime;
  447.  
  448.       /* File exists, return success */
  449.       return 0;
  450.    }
  451.    return 1;
  452. }
  453.  
  454.  
  455.  
  456. #ifndef SFX
  457.  
  458. /************************/
  459. /*  Function version()  */
  460. /************************/
  461.  
  462. void version(__G)
  463.     __GDEF
  464. {
  465.     int len;
  466.     char liblvlmsg [50+1];
  467.  
  468.     union {
  469.        unsigned int iVRM;
  470.        struct {
  471.           unsigned int v:8;
  472.           unsigned int r:8;
  473.           unsigned int m:8;
  474.        } xVRM;
  475.     } VRM;
  476.  
  477.     /* Break down the runtime library level */
  478.     VRM.iVRM = __librel();
  479.     sprintf(liblvlmsg, ".  Runtime level V%dR%dM%d",
  480.             VRM.xVRM.v, VRM.xVRM.r, VRM.xVRM.m);
  481.  
  482.  
  483.     /* Output is in the form "Compiled with %s%s for %s%s%s%s" */
  484.  
  485.     len = sprintf((char *)slide, LoadFarString(CompiledWith),
  486.  
  487.     /* Add compiler name and level */
  488.       "C/370", "",          /* Assumed.  Can't get compiler lvl(?) */
  489.  
  490.     /* Add compile environment */
  491. #ifdef VM_CMS
  492.       "VM/CMS",
  493. #else
  494.       "MVS",
  495. #endif
  496.  
  497.     /* Add timestamp */
  498. #ifdef __TIMESTAMP
  499.       " on ", __TIMESTAMP,
  500. #else
  501.       "", "",
  502. #endif
  503.       liblvlmsg
  504.     );
  505.  
  506.     (*G.message)((zvoid *)&G, slide, (ulg)len, 0);
  507.  
  508. } /* end function version() */
  509.  
  510. #endif /* !SFX */
  511.