home *** CD-ROM | disk | FTP | other *** search
/ Amiga Elysian Archive / AmigaElysianArchive.iso / compress / zoosrc20.zoo / vms.c < prev    next >
C/C++ Source or Header  |  1989-07-25  |  10KB  |  366 lines

  1. #ifndef LINT
  2. /* @(#) vms.c 1.4 87/07/26 22:48:45 */
  3. /* @(#) vms.c 2.2 88/01/09 03:47:52 */
  4. #endif /* LINT */
  5.  
  6. /* machine.c for VMS */
  7.  
  8. /****************
  9. Date and time functions are standard UNIX-style functions, except that
  10. VAX/VMS does not know about timezones.  "nixtime.i" will be included 
  11. by machine.c.
  12. */
  13.  
  14. #include <stat.h>
  15. #include <time.h>
  16.  
  17. /* Function isuadir() returns 1 if the supplied filename is a directory, 
  18. else it returns 0.  
  19. */
  20.  
  21. int isuadir (file)
  22. char *file;
  23. {
  24.    struct stat buf;           /* buffer to hold file information */
  25.    if (stat (file, &buf) == -1) {
  26.       return (0);             /* inaccessible -- assume not dir */
  27.    } else {
  28.       if (buf.st_mode & S_IFDIR)
  29.          return (1);
  30.       else
  31.          return (0);
  32.    }
  33. }
  34.  
  35. /****************
  36. Function fixfname() converts the supplied filename to a syntax
  37. legal for the host system.  It is used during extraction.  We
  38. allow a maximum of one dot in the filename, and it must not
  39. be at the beginning.  We also truncate the number of charac-
  40. ters preceding and following the dot to at most 39.
  41. */
  42.  
  43. char *strchr();
  44.  
  45. char *fixfname(fname)
  46. char *fname;
  47. {
  48.    char *p;
  49.    char *dotpos;
  50.    static char legal[] = 
  51.       "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ$_.0123456789";
  52.  
  53.    /* convert all characters to legal characters */
  54.    for (p = fname;  *p != '\0';  p++)
  55.       if (strchr (legal, *p) == 0) {
  56.          if (*p == '-' || *p == ' ')
  57.             *p = '_';
  58.          else
  59.             *p = legal [ *p % 26 ];
  60.       }
  61.  
  62.    /* first char can't be dot */
  63.    if (*fname == '.')
  64.       *fname = 'X';
  65.  
  66.    /* find embedded dot if any */
  67.    dotpos = strchr (fname, '.');
  68.  
  69.    if (dotpos != NULL) {
  70.       for (p = dotpos+1;  *p != '\0';  p++)  /* remove 2nd dot onwards */
  71.          if (*p == '.')
  72.             *p = '_';
  73.       if (dotpos - fname + 1 > 39) {  /* more than 39 before dot not allowed */
  74.          char *q;
  75.          p = fname + 39;
  76.          q = dotpos;
  77.          while (*p++ = *q++)  /* the notational convenience is considerable */
  78.             ;
  79.          dotpos = strchr (fname, '.');
  80.       }
  81.       if (strlen (dotpos + 1) > 39)  /* more than 39 after dot not allowed */
  82.          *(dotpos + 39 + 1) = '\0';
  83.    } else
  84.       *(fname + 39) = '\0'; /* no dots, just truncate to 39 characters */
  85.    return (fname);
  86. }
  87.  
  88. /*
  89. Function gettz(), returns the offset from GMT in seconds of the
  90. local time, taking into account daylight savings time -- or it
  91. would, if VAX/VMS knew about timezones!  It's just a no-op.
  92. */
  93. long gettz()
  94. {
  95.    return 0L;
  96. }
  97.  
  98. /* Standard UNIX-compatible time functions */
  99. #include "nixtime.i"
  100.  
  101. /*
  102. Function utime() is just a stub.  VMS C doesn't have it or
  103. an equivalent.
  104. */
  105. int utime (fname) char *fname; {}
  106.  
  107. /*
  108. Function unlink() will delete a file using the VMS C delete()
  109. function.
  110. */
  111. int unlink (fname)
  112. char *fname;
  113. {
  114.    return (delete (fname));
  115. }
  116.  
  117. /*
  118. Function zooexit() receives attempts at exit.  It always invokes
  119. exit() with status=1.
  120. */
  121. int zooexit (status)
  122. int status;
  123. {
  124.    exit (1);
  125. }
  126.  
  127.  
  128. /*
  129. Function rename() renames a file.  
  130. Thanks to Owen Anthony <bsu-cs!anthony>.
  131. */
  132.  
  133. #include <descrip.h>
  134.  
  135. #ifndef VMS_RENAME /* if not using VMS 4.6 library rename() */
  136. int rename (new_name, old_name)
  137. char *new_name, *old_name;
  138. {
  139.    int status;
  140.    struct dsc$descriptor_s file1, file2;
  141.    file1.dsc$w_length = strlen (old_name);  /* descriptor for old name */
  142.    file1.dsc$a_pointer = old_name;
  143.    file1.dsc$b_class = DSC$K_CLASS_S;
  144.    file1.dsc$b_dtype = DSC$K_DTYPE_T;
  145.    file2.dsc$w_length = strlen (new_name);  /* descriptor for new name */
  146.    file2.dsc$a_pointer = new_name;
  147.    file2.dsc$b_class = DSC$K_CLASS_S;
  148.    file2.dsc$b_dtype = DSC$K_DTYPE_T;
  149.  
  150.    status = LIB$RENAME_FILE (&file1, &file2);
  151.  
  152.    return ((status & ~1) == 1);
  153. }
  154. #endif /* VMS_RENAME */
  155.  
  156. /*
  157. Function specfname() modifies filenames before they are stored
  158. in an archive.  Currently we remove any trailing version field,
  159. and then any trailing dot.
  160. */
  161. char *specfname (fname)
  162. char *fname;
  163. {
  164.    char *p;
  165.    p = strchr (fname, ';');
  166.    if (p != NULL)
  167.       *p = '\0';
  168.    if (*fname != '\0') {
  169.       p = fname + strlen (fname) - 1; /* point to last char */
  170.       if (*p == '.')                  /* remove any trailing dot */
  171.          *p = '\0';
  172.    }
  173.    return (fname);
  174. }
  175.  
  176. /* 
  177. Function specdir() modifies directory names before they are stored
  178. in an archive.  We remove any leading device name or logical
  179. name and and the [ and ] that bracket any directory name.
  180. Then we change any dots in the directory name to slashes.
  181. */
  182.  
  183. #if 0
  184. /* test stub that just truncates dir to null string */
  185. char *specdir (fname) char *fname;
  186. { *fname = '\0'; return (fname); }
  187. #else
  188.  
  189. char *specdir (fname)
  190. char *fname;
  191. {
  192.    char *p;
  193.    char tmpstr[LFNAMESIZE];
  194.  
  195.    p = strchr (fname, ':');      /* remove chars upto and including : */
  196.    if (p != NULL) {
  197.       strcpy (tmpstr, p+1);
  198.       strcpy (fname, tmpstr);
  199.    }
  200.  
  201.    p = strchr (fname, '[');      /* remove chars upto and including [ */
  202.    if (p != NULL) {
  203.       strcpy (tmpstr, p+1);
  204.       strcpy (fname, tmpstr);
  205.    }
  206.  
  207.    p = strchr (fname, ']');      /* truncate at ] */
  208.    if (p != NULL) {
  209.       if (*(p+1) != '\0')
  210.          prterror ('w', "Trailing garbage in directory name\n");
  211.       *p = '\0';
  212.    }
  213.  
  214.    for (p = fname;  *p != '\0';  p++)   /* change dots to slashes */
  215.       if (*p == '.')
  216.          *p = '/';
  217.  
  218.    /* make sure there is a leading slash -- just a hack for now */
  219.    if (*fname != '/') {
  220.       strcpy (tmpstr, fname);
  221.       strcpy (fname, "/");
  222.       strcat (fname, tmpstr);
  223.    }
  224.  
  225. #ifdef DEBUG
  226. printf ("dir name transformed to \"%s\"\n", fname);
  227. #endif
  228. }
  229. #endif
  230.  
  231. #define  FMAX  3        /* Number of different filename patterns */
  232.  
  233. char *nextfile (what, filespec, fileset)
  234. int what;                        /* whether to initialize or match      */
  235. register char *filespec;         /* filespec to match if initializing   */
  236. register int fileset;            /* which set of files                  */
  237. {
  238.    int status;
  239.    char *p;                      /* temp ptr */
  240.    struct dsc$descriptor_s d_fwild, d_ffound;
  241.    static int first_time [FMAX+1];
  242.    static char saved_fspec [FMAX+1][PATHSIZE];  /* our own copy of filespec */
  243.    static char found_fspec [FMAX+1][PATHSIZE];  /* matched filename */
  244.    static unsigned long context [FMAX+1];    /* needed by VMS */
  245.    if (what == 0) {
  246.       strcpy (saved_fspec[fileset], filespec);  /* save the filespec */
  247.       first_time[fileset] = 1;
  248.       return (0);
  249.    }
  250.  
  251.    /* Reach here if what is not 0, so it must be 1 */
  252.  
  253.    /* Create a descriptor for the wildcarded filespec */
  254.    d_fwild.dsc$w_length = strlen (saved_fspec[fileset]);
  255.    d_fwild.dsc$a_pointer = saved_fspec[fileset];
  256.    d_fwild.dsc$b_class = DSC$K_CLASS_S;
  257.    d_fwild.dsc$b_dtype = DSC$K_DTYPE_T;
  258.  
  259.    d_ffound.dsc$w_length = sizeof (found_fspec[fileset]);
  260.    d_ffound.dsc$a_pointer = found_fspec[fileset];
  261.    d_ffound.dsc$b_class = DSC$K_CLASS_S;
  262.    d_ffound.dsc$b_dtype = DSC$K_DTYPE_T;
  263.  
  264.    if (first_time[fileset]) {
  265.       first_time[fileset] = 0;
  266.       context[fileset] = 0L;   /* tell VMS this is first search */
  267.    }
  268.    status = LIB$FIND_FILE (&d_fwild, &d_ffound, &context[fileset]);
  269.    status = status & 1;    /* use only lowest bit */
  270.  
  271.    if (status == 0) {
  272.       LIB$FIND_FILE_END (&context[fileset]);
  273.       return ((char *) 0);
  274.    } else {
  275.       found_fspec[fileset][d_ffound.dsc$w_length] = '\0'; /* just in case */
  276.       p = found_fspec[fileset];
  277.       while (*p != ' ' && *p != '\0')
  278.          p++;
  279.       if (*p != '\0')
  280.          *p = '\0';
  281.       return (found_fspec[fileset]);
  282.    }
  283. }
  284.  
  285. /*
  286. Function vmsmkdir() converts the received directory name into VMS
  287. format and then creates a directory.
  288. */
  289. int vmsmkdir (subdir)
  290. char *subdir;
  291. {
  292.    char *lastptr();
  293.    char *p;
  294.    char tmp[LFNAMESIZE];
  295.  
  296.    p = subdir;
  297.  
  298.    /* leading "/" => "[", otherwise => "[." */
  299.    if (*p == '/') {
  300.       strcpy (tmp, "[");
  301.       p++;
  302.    } else {
  303.       strcpy (tmp, "[.");
  304.       while (*p == '/' || *p == '.')
  305.          p++;
  306.    }
  307.  
  308.    strcat (tmp, p);
  309.  
  310.    /* 
  311.    VMS doesn't like dots in directory names, so we convert them to
  312.    underscores.  Leave first two characters untouched, because
  313.    we don't want to corrupt a leading "[." into "[_".
  314.    */
  315.    for (p = tmp + 2;  *p != '\0';  p++)
  316.       if (*p == '.')
  317.          *p = '_';
  318.  
  319.    /* convert all slashes to dots */
  320.    for (p = tmp; *p != '\0';  p++)
  321.       if (*p == '/')
  322.          *p = '.';
  323.  
  324.    /* Remove any trailing dot */
  325.    p = lastptr (tmp);
  326.    if (*p == '.')
  327.       *p = '\0';
  328.  
  329.    /* append closing bracket */
  330.    strcat (tmp, "]");
  331. #if 0
  332.    printf ("\nmaking directory \"%s\"\n", tmp);
  333. #endif
  334.    return (mkdir (tmp, 0));
  335. }
  336.  
  337. /*
  338. Function spec_wild() transforms a pattern supplied on the command line into one
  339. suitable for wildcard expansion in the most efficient way possible.  We change
  340. each "?" to "%" but let "*" remain unchanged.  We also append a ".*" if the
  341. pattern contains no dot, so "*" will be interpreted as "*.*" for VMS globbing. 
  342. */
  343. char *spec_wild (arg)
  344. char *arg;
  345. {
  346.    char *p;
  347. #ifdef DEBUG
  348.    printf ("spec_wild: arg = [%s]\n", arg);
  349. #endif
  350.    if (*lastptr (arg) == ']')      /* add *.* if no filename */
  351.       strcat (arg, "*.*");
  352.    p = nameptr (arg);              /* point p to filename part */
  353.  
  354.    /* if no dot in name append ".*" */
  355.    if (strchr (p, '.') == NULL)
  356.       strcat (p, ".*");
  357.  
  358.    for ( ; *p != '\0';  p++)        /* change every "?" to "%" */
  359.       if (*p == '?')
  360.          *p = '%';
  361. #ifdef DEBUG
  362.    printf ("spec_wild: arg changed to [%s]\n", arg);
  363. #endif
  364.    return (arg);
  365. }
  366.