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 */
 |