which included commits to RCS files with non-trunk default branches. git-svn-id: svn://10.65.10.50/trunk@5403 c028cbd2-c16b-5b4b-a496-9718f37d4682
		
			
				
	
	
		
			511 lines
		
	
	
		
			13 KiB
		
	
	
	
		
			C
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			511 lines
		
	
	
		
			13 KiB
		
	
	
	
		
			C
		
	
	
		
			Executable File
		
	
	
	
	
| /*---------------------------------------------------------------------------
 | |
|  
 | |
|   vmmvs.c (for both VM/CMS and MVS)
 | |
|  
 | |
|   Contains:  vmmvs_open_infile()
 | |
|              open_outfile()
 | |
|              find_vms_attrs()
 | |
|              flush()
 | |
|              close_outfile()
 | |
|              close_infile()
 | |
|              getVMMVSexfield()
 | |
|              do_wild()
 | |
|              mapattr()
 | |
|              mapname()
 | |
|              checkdir()
 | |
|              check_for_newer()
 | |
|              stat()
 | |
|              version()
 | |
|  
 | |
|   ---------------------------------------------------------------------------*/
 | |
|  
 | |
|  
 | |
| #define UNZIP_INTERNAL
 | |
| #include "unzip.h"
 | |
|  
 | |
|  
 | |
| /********************************/
 | |
| /* Function vmmvs_open_infile() */
 | |
| /********************************/
 | |
|  
 | |
| FILE *vmmvs_open_infile(__G)
 | |
|    __GDEF
 | |
| {
 | |
|    FILE *fzip;
 | |
|  
 | |
|    G.tempfn = NULL;
 | |
|    if ((fzip = fopen(G.zipfn,"rb,recfm=fb")) == (FILE *)NULL) {
 | |
|       size_t cnt;
 | |
|       char *buf;
 | |
|       FILE *in, *out;
 | |
|  
 | |
|       if ((buf = (char *)malloc(32768)) == NULL) return NULL;
 | |
|       if ((G.tempfn = tmpnam(NULL)) == NULL) return NULL;
 | |
|       if ((in = fopen(G.zipfn,"rb")) != NULL &&
 | |
|           (out = fopen(G.tempfn,"wb,recfm=fb,lrecl=1")) != NULL) {
 | |
|          Trace((stdout,"Converting ZIP file to fixed record format...\n"));
 | |
|          while (!feof(in)) {
 | |
|             cnt= fread(buf,1,32768,in);
 | |
|             if (cnt) fwrite(buf,1,cnt,out);
 | |
|          }
 | |
|       }
 | |
|       else {
 | |
|          free(buf);
 | |
|          fclose(out);
 | |
|          fclose(in);
 | |
|          return NULL;
 | |
|       }
 | |
|       free(buf);
 | |
|       fclose(out);
 | |
|       fclose(in);
 | |
|  
 | |
|       fzip = fopen(G.tempfn,"rb,recfm=fb");
 | |
|       if (fzip == (FILE *)NULL) return NULL;
 | |
|  
 | |
|       /* Update the G.ziplen value since it might have changed after
 | |
|          the reformatting copy. */
 | |
|       fseek(fzip,0L,SEEK_SET);
 | |
|       fseek(fzip,0L,SEEK_END);
 | |
|       G.ziplen = ftell(fzip);
 | |
|    }
 | |
|  
 | |
|    return fzip;
 | |
| }
 | |
|  
 | |
|  
 | |
| /***************************/
 | |
| /* Function open_outfile() */
 | |
| /***************************/
 | |
|  
 | |
| int open_outfile(__G)           /* return 1 if fail */
 | |
|     __GDEF
 | |
| {
 | |
|     char type[100];
 | |
|     char *mode = NULL;
 | |
|  
 | |
|     if (G.pInfo->textmode)
 | |
|         mode = FOPWT;
 | |
|     else {
 | |
|         if (G.lrec.extra_field_length > EB_HEADSIZE) {
 | |
|             ush leb_id   = makeword(&G.extra_field[EB_ID]);
 | |
|             ush leb_dlen = makeword(&G.extra_field[EB_LEN]);
 | |
|  
 | |
|             if ((leb_id == EF_VMCMS || leb_id == EF_MVS) &&
 | |
|                 (leb_dlen <= (G.lrec.extra_field_length - EB_HEADSIZE)) &&
 | |
|                 (getVMMVSexfield(type, G.extra_field, (unsigned)leb_dlen) > 0))
 | |
|                 mode = type;
 | |
|         }
 | |
|     }
 | |
|     if (mode == NULL) mode = FOPW;
 | |
|  
 | |
|     if ((G.outfile = fopen(G.filename, mode)) == (FILE *)NULL) {
 | |
|         Info(slide, 0x401, ((char *)slide, "\nerror:  cannot create %s\n",
 | |
|              G.filename));
 | |
|         return 1;
 | |
|     }
 | |
|     return 0;
 | |
| } /* end function open_outfile() */
 | |
|  
 | |
|  
 | |
| /****************************/
 | |
| /* Function close_outfile() */
 | |
| /****************************/
 | |
|  
 | |
| void close_outfile(__G)
 | |
|    __GDEF
 | |
| {
 | |
|    fclose(G.outfile);
 | |
| } /* end function close_outfile() */
 | |
|  
 | |
|  
 | |
| /****************************/
 | |
| /* Function close_infile() */
 | |
| /****************************/
 | |
|  
 | |
| void close_infile(__G)
 | |
|    __GDEF
 | |
| {
 | |
|    fclose(G.zipfd);
 | |
|  
 | |
|    /* If we're working from a temp file, erase it now */
 | |
|    if (G.tempfn)
 | |
|       remove(G.tempfn);
 | |
|  
 | |
| } /* end function close_infile() */
 | |
|  
 | |
|  
 | |
|  
 | |
| /******************************/
 | |
| /* Function getVMMVSexfield() */
 | |
| /******************************/
 | |
|  
 | |
| extent getVMMVSexfield(type, ef_block, datalen)
 | |
|     char *type;
 | |
|     uch *ef_block;
 | |
|     unsigned datalen;
 | |
| {
 | |
|     fldata_t *fdata = (fldata_t *) &ef_block[4];
 | |
|  
 | |
|     if (datalen < sizeof(fldata_t))
 | |
|         return 0;
 | |
|  
 | |
|     strcpy(type, "w");
 | |
|     strcat(type,  fdata->__openmode == __TEXT   ? ""
 | |
|                  :fdata->__openmode == __BINARY ? "b"
 | |
|                  :fdata->__openmode == __RECORD ? "b,type=record"
 | |
|                  : "");
 | |
|     strcat(type, ",recfm=");
 | |
|     strcat(type,  fdata->__recfmF? "F"
 | |
|                  :fdata->__recfmV? "V"
 | |
|                  :fdata->__recfmU? "U"
 | |
|                  :                 "?");
 | |
|     if (fdata->__recfmBlk) strcat(type, "B");
 | |
|     if (fdata->__recfmS)   strcat(type, "S");
 | |
|     if (fdata->__recfmASA) strcat(type, "A");
 | |
|     if (fdata->__recfmM)   strcat(type, "M");
 | |
|     sprintf(type+strlen(type), ",lrecl=%ld", fdata->__recfmV
 | |
|                                               ? fdata->__maxreclen+4
 | |
|                                               : fdata->__maxreclen);
 | |
|     sprintf(type+strlen(type), ",blksize=%ld", fdata->__blksize);
 | |
|  
 | |
|     return strlen(type);
 | |
| } /* end function getVMMVSexfield() */
 | |
|  
 | |
|  
 | |
|  
 | |
| #ifndef SFX
 | |
|  
 | |
| /**********************/
 | |
| /* Function do_wild() */   /* for porting:  dir separator; match(ignore_case) */
 | |
| /**********************/
 | |
|  
 | |
| char *do_wild(__G__ wld)
 | |
|     __GDEF
 | |
|     char *wld;             /* only used first time on a given dir */
 | |
| {
 | |
|     static int First = 0;
 | |
|     static char filename[256];
 | |
|  
 | |
|     if (First == 0) {
 | |
|        First = 1;
 | |
|        strcpy( filename, wld );
 | |
|        return filename;
 | |
|     }
 | |
|     else
 | |
|        return (char *)NULL;
 | |
|  
 | |
| } /* end function do_wild() */
 | |
|  
 | |
| #endif /* !SFX */
 | |
|  
 | |
|  
 | |
|  
 | |
| /************************/
 | |
| /*  Function mapattr()  */
 | |
| /************************/
 | |
|  
 | |
| int mapattr(__G)
 | |
|      __GDEF
 | |
| {
 | |
|     return 0;
 | |
| }
 | |
|  
 | |
| /************************/
 | |
| /*  Function mapname()  */
 | |
| /************************/
 | |
|  
 | |
| int mapname(__G__ renamed)
 | |
|             /* returns: */
 | |
|             /* 0 (PK_COOL) if no error, */
 | |
|             /* 1 (PK_WARN) if caution (filename trunc), */
 | |
|             /* 2 (PK_ERR)  if warning (skip file because dir doesn't exist), */
 | |
|             /* 3 (PK_BADERR) if error (skip file), */
 | |
|             /* 10 if no memory (skip file) */
 | |
|     __GDEF
 | |
|     int renamed;
 | |
| {
 | |
|     char newname[68], *lbar;
 | |
| #ifdef MVS
 | |
|     char *pmember;
 | |
| #endif
 | |
|     int name_changed = 0;
 | |
|  
 | |
| #ifdef MVS
 | |
|     while ((lbar = strrchr(G.filename,'_')) != NULL) {
 | |
|        strcpy(lbar,(lbar)+1);
 | |
|        name_changed = 1;
 | |
|     }
 | |
|     /* '-' and '+' ARE valid chars for CMS.  --RGH  */
 | |
|     while ((lbar = strrchr(G.filename,'+')) != NULL) {
 | |
|        strcpy(lbar,(lbar)+1);
 | |
|        name_changed = 1;
 | |
|     }
 | |
|     while ((lbar = strrchr(G.filename,'-')) != NULL) {
 | |
|        strcpy(lbar,(lbar)+1);
 | |
|        name_changed = 1;
 | |
|     }
 | |
| #endif
 | |
|  
 | |
|     while ((lbar = strrchr(G.filename,'(')) != NULL) {
 | |
|        strcpy(lbar,(lbar)+1);
 | |
|        name_changed = 1;
 | |
|     }
 | |
|     while ((lbar = strrchr(G.filename,')')) != NULL) {
 | |
|        strcpy(lbar,(lbar)+1);
 | |
|        name_changed = 1;
 | |
|     }
 | |
|  
 | |
| #ifdef VM_CMS
 | |
|     if ((lbar = strrchr(G.filename,'/')) != NULL) {
 | |
|         strcpy((char *)newname,(char *)((lbar)+1));
 | |
|         printf("WARNING: file '%s' renamed as '%s'\n",G.filename,newname);
 | |
|         strcpy(G.filename,(char *)newname);
 | |
|         name_changed = 1;
 | |
|     }
 | |
| #else /* MVS */
 | |
|     if ((pmember = strrchr(G.filename,'/')) == NULL)
 | |
|         pmember = G.filename;
 | |
|     else
 | |
|         pmember++;
 | |
|  
 | |
|     /* search for extension in file name */
 | |
|     if ((lbar = strrchr(pmember,'.')) != NULL) {
 | |
|         *lbar++ = '\0';
 | |
|         strcpy(newname, pmember);
 | |
|         strcpy(pmember, lbar);
 | |
|         strcat(pmember, "(");
 | |
|         strcat(pmember, newname);
 | |
|         strcat(pmember, ")");
 | |
|     }
 | |
|  
 | |
|     /* Remove all 'internal' dots '.', to prevent false consideration as
 | |
|      * MVS path delimiters! */
 | |
|     while ((lbar = strrchr(G.filename,'.')) != NULL) {
 | |
|         strcpy(lbar,(lbar)+1);
 | |
|         name_changed = 1;
 | |
|     }
 | |
|  
 | |
|     /* Finally, convert path delimiters from internal '/' to external '.' */
 | |
|     while ((lbar = strchr(G.filename,'/')) != NULL)
 | |
|         *lbar = '.';
 | |
| #endif /* ?VM_CMS */
 | |
|  
 | |
| #ifndef MVS
 | |
|     if ((lbar = strchr(G.filename,'.')) == (char *)NULL) {
 | |
|         printf("WARNING: file '%s' has NO extension - renamed as '%s.NONAME'\n"\
 | |
|               ,G.filename,G.filename);
 | |
|        strcat(G.filename,".NONAME");
 | |
|        name_changed = 1;
 | |
|     }
 | |
| #endif
 | |
|     checkdir(__G__ G.filename, GETPATH);
 | |
|  
 | |
|     return name_changed;
 | |
|  
 | |
| } /* end function mapname() */
 | |
|  
 | |
|  
 | |
| int checkdir(__G__ pathcomp, flag)
 | |
|     __GDEF
 | |
|     char *pathcomp;
 | |
|     int flag;
 | |
| /*
 | |
|  * returns:  1 - (on APPEND_NAME) truncated filename
 | |
|  *           2 - path doesn't exist, not allowed to create
 | |
|  *           3 - path doesn't exist, tried to create and failed; or
 | |
|  *               path exists and is not a directory, but is supposed to be
 | |
|  *           4 - path is too long
 | |
|  *          10 - can't allocate memory for filename buffers
 | |
|  */
 | |
| {
 | |
|     static int rootlen = 0;      /* length of rootpath */
 | |
|     static char *rootpath;       /* user's "extract-to" directory */
 | |
|  
 | |
| #   define FN_MASK   7
 | |
| #   define FUNCTION  (flag & FN_MASK)
 | |
|  
 | |
| #if (!defined(SFX) || defined(SFX_EXDIR))
 | |
|     if (FUNCTION == ROOT) {
 | |
|         Trace((stderr, "initializing root path to [%s]\n", pathcomp));
 | |
|         if (pathcomp == (char *)NULL) {
 | |
|             rootlen = 0;
 | |
|         }
 | |
|         else if ((rootlen = strlen(pathcomp)) > 0) {
 | |
|             if ((rootpath = (char *)malloc(rootlen+1)) == NULL) {
 | |
|                 rootlen = 0;
 | |
|                 return 10;
 | |
|             }
 | |
|             strcpy(rootpath, pathcomp);
 | |
|             Trace((stderr, "rootpath now = [%s]\n", rootpath));
 | |
|         }
 | |
|         return 0;
 | |
|     }
 | |
| #endif /* !SFX || SFX_EXDIR */
 | |
|  
 | |
| /*---------------------------------------------------------------------------
 | |
|     GETPATH:  copy full path to the string pointed at by pathcomp, and free
 | |
|     buildpath.
 | |
|   ---------------------------------------------------------------------------*/
 | |
|  
 | |
|     if (FUNCTION == GETPATH) {
 | |
|         if (rootlen > 0) {
 | |
| #ifdef VM_CMS                     /* put the exdir after the filename */
 | |
|            strcat(pathcomp,".");       /* used as minidisk to be save on  */
 | |
|            strcat(pathcomp,rootpath);
 | |
| #else /* MVS */
 | |
|            char newfilename[PATH_MAX];
 | |
|            char *start_fname;
 | |
|  
 | |
|            strcpy(newfilename,rootpath);
 | |
|            if (strchr(pathcomp,'(') == NULL) {
 | |
|               if ((start_fname = strrchr(pathcomp,'.')) == NULL) {
 | |
|                  start_fname = pathcomp;
 | |
|               }
 | |
|               else {
 | |
|                  *start_fname++ = '\0';
 | |
|                  strcat(newfilename, ".");
 | |
|                  strcat(newfilename, pathcomp);
 | |
|               }
 | |
|               strcat(newfilename,"(");
 | |
|               strcat(newfilename,start_fname);
 | |
|               strcat(newfilename,")");
 | |
|            }
 | |
|            else {
 | |
|               strcat(newfilename,".");
 | |
|               strcat(newfilename,pathcomp);
 | |
|            }
 | |
|            Trace((stdout, "new dataset : %s\n", newfilename));
 | |
|            strcpy(pathcomp,newfilename);
 | |
| #endif /* ?VM_CMS */
 | |
|         }
 | |
|         return 0;
 | |
|     }
 | |
|  
 | |
| /*---------------------------------------------------------------------------
 | |
|     END:  free rootpath, immediately prior to program exit.
 | |
|   ---------------------------------------------------------------------------*/
 | |
|  
 | |
|     if (FUNCTION == END) {
 | |
|         Trace((stderr, "freeing rootpath\n"));
 | |
|         if (rootlen > 0)
 | |
|             free(rootpath);
 | |
|         return 0;
 | |
|     }
 | |
|  
 | |
|     return 99;  /* should never reach */
 | |
|  
 | |
| } /* end function checkdir() */
 | |
|  
 | |
|  
 | |
| /******************************/
 | |
| /* Function check_for_newer() */  /* used for overwriting/freshening/updating */
 | |
| /******************************/
 | |
|  
 | |
| int check_for_newer(__G__ filename)  /* return 1 if existing file is newer */
 | |
|     __GDEF                           /*  or equal; 0 if older; -1 if doesn't */
 | |
|     char *filename;                  /*  exist yet */
 | |
| {
 | |
|     FILE *stream;
 | |
|  
 | |
|     if ((stream = fopen(filename, "r")) != (FILE *)NULL) {
 | |
|        fclose(stream);
 | |
|        /* File exists, assume it is "newer" than archive entry. */
 | |
|        return EXISTS_AND_NEWER;
 | |
|     }
 | |
|     /* File does not exist. */
 | |
|     return DOES_NOT_EXIST;
 | |
| } /* end function check_for_newer() */
 | |
|  
 | |
|  
 | |
| /*********************/
 | |
| /*  Function stat()  */
 | |
| /*********************/
 | |
|  
 | |
| int stat(const char *path, struct stat *buf)
 | |
| {
 | |
|    FILE *fp;
 | |
|    char fname[PATH_MAX];
 | |
|    time_t ltime;
 | |
|  
 | |
|    if ((fp = fopen(path, "rb")) != NULL) {
 | |
|       fldata_t fdata;
 | |
|       if (fldata( fp, fname, &fdata ) == 0) {
 | |
|          buf->st_dev  = fdata.__device;
 | |
|          buf->st_mode = *(short *)(&fdata);
 | |
|       }
 | |
|  
 | |
|       /* Determine file size by seeking to EOF */
 | |
|       fseek(fp,0L,SEEK_END);
 | |
|       buf->st_size = ftell(fp);
 | |
|       fclose(fp);
 | |
|  
 | |
|       /* set time fields in stat buf to current time. */
 | |
|       time(<ime);
 | |
|       buf->st_atime =
 | |
|       buf->st_mtime =
 | |
|       buf->st_ctime = ltime;
 | |
|  
 | |
|       /* File exists, return success */
 | |
|       return 0;
 | |
|    }
 | |
|    return 1;
 | |
| }
 | |
|  
 | |
|  
 | |
|  
 | |
| #ifndef SFX
 | |
|  
 | |
| /************************/
 | |
| /*  Function version()  */
 | |
| /************************/
 | |
|  
 | |
| void version(__G)
 | |
|     __GDEF
 | |
| {
 | |
|     int len;
 | |
|     char liblvlmsg [50+1];
 | |
|  
 | |
|     union {
 | |
|        unsigned int iVRM;
 | |
|        struct {
 | |
|           unsigned int v:8;
 | |
|           unsigned int r:8;
 | |
|           unsigned int m:8;
 | |
|        } xVRM;
 | |
|     } VRM;
 | |
|  
 | |
|     /* Break down the runtime library level */
 | |
|     VRM.iVRM = __librel();
 | |
|     sprintf(liblvlmsg, ".  Runtime level V%dR%dM%d",
 | |
|             VRM.xVRM.v, VRM.xVRM.r, VRM.xVRM.m);
 | |
|  
 | |
|  
 | |
|     /* Output is in the form "Compiled with %s%s for %s%s%s%s" */
 | |
|  
 | |
|     len = sprintf((char *)slide, LoadFarString(CompiledWith),
 | |
|  
 | |
|     /* Add compiler name and level */
 | |
|       "C/370", "",          /* Assumed.  Can't get compiler lvl(?) */
 | |
|  
 | |
|     /* Add compile environment */
 | |
| #ifdef VM_CMS
 | |
|       "VM/CMS",
 | |
| #else
 | |
|       "MVS",
 | |
| #endif
 | |
|  
 | |
|     /* Add timestamp */
 | |
| #ifdef __TIMESTAMP
 | |
|       " on ", __TIMESTAMP,
 | |
| #else
 | |
|       "", "",
 | |
| #endif
 | |
|       liblvlmsg
 | |
|     );
 | |
|  
 | |
|     (*G.message)((zvoid *)&G, slide, (ulg)len, 0);
 | |
|  
 | |
| } /* end function version() */
 | |
|  
 | |
| #endif /* !SFX */
 |