home *** CD-ROM | disk | FTP | other *** search
/ vsiftp.vmssoftware.com / VSIPUBLIC@vsiftp.vmssoftware.com.tar / FREEWARE / FREEWARE40.ZIP / flistfrontend / src / flcrea.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-10-28  |  3.4 KB  |  177 lines

  1. #ifndef NO_IDENT
  2. static char *Id = "$Id: flcrea.c,v 1.2 1995/10/27 23:09:33 tom Exp $";
  3. #endif
  4.  
  5. /*
  6.  * Title:    flcrea.c
  7.  * Author:    T.E.Dickey
  8.  * Created:    27 Oct 1995
  9.  * Last update:
  10.  *
  11.  * Function:    This module supports an create-function for "FLIST".
  12.  *        No options, no wildcards.
  13.  */
  14.  
  15. #include    <starlet.h>
  16. #include    <stsdef.h>
  17. #include    <rms.h>
  18.  
  19. #include    <stdlib.h>
  20. #include    <stdio.h>
  21. #include    <errno.h>
  22. #include    <string.h>    /* 'strerror()', etc. */
  23. #include    <unixio.h>    /* 'creat()' */
  24. #include    <unixlib.h>    /* 'mkdir()' */
  25.  
  26. #include    "bool.h"
  27. #include    "dclarg.h"
  28. #include    "flist.h"    /* 'flist_sysmsg()' */
  29.  
  30. #include    "dds.h"
  31. #include    "dircmd.h"
  32. #include    "dirent.h"
  33. #include    "pathup.h"
  34. #include    "rmsinit.h"
  35.  
  36. #include    "strutils.h"
  37.  
  38. static    int    looks_like_directory (char *filespec);
  39.  
  40. tDIRCMD(flcrea)
  41. {
  42.     unsigned status;
  43.     FILENT    znew, *z = &znew;
  44.     char    leaf_0[MAX_PATH];
  45.     char    full_1[MAX_PATH];
  46.     char    full_2[MAX_PATH];
  47.     char    *spec    = dclinx (xdcl_, 1, 0);
  48.     int    fd;
  49.     int    code;
  50.     char    *s;
  51.  
  52.     /*
  53.      * If the new item looks like a directory, create a directory.
  54.      */
  55.     switch ((code = looks_like_directory(spec)))
  56.     {
  57.     case 3:    /* Make both directory and filename */
  58.         for (s = spec + strlen(spec) - 1; (s - spec) >= 0; s--)
  59.         {
  60.             if (*s == '>' || *s == ']')
  61.             {
  62.                 s++;
  63.                 break;
  64.             }
  65.         }
  66.         strcpy(leaf_0, s);
  67.         *s = EOS;
  68.         /* FALLTHRU */
  69.         goto bracketed_name;
  70.  
  71.     case 2:    /* Translate name to bracketed form */
  72.         status = dirent_chop (z, spec, (struct NAM *)0);
  73.         if (! $VMS_STATUS_SUCCESS(status))
  74.         {
  75.             flist_sysmsg (status);
  76.             return;
  77.         }
  78.         (void)pathdown (spec = full_1, zPATHOF(z), z->fname);
  79.         /*FALLTHRU*/
  80.  
  81.     bracketed_name:
  82.     case 1: /* Make a directory */
  83.         if (mkdir(spec, 0777) < 0)
  84.         {
  85.             warn("%s: %s", spec, strerror(errno));
  86.             return;
  87.         }
  88.         /* Translate the name into a ".dir" form, since that's how
  89.          * it'll get put into the file list
  90.          */
  91.         if (!pathup(full_2, spec))
  92.         {
  93.             warn("%s: unexpected error", spec);
  94.             return;
  95.         }
  96.         if (code != 3)
  97.         {
  98.             spec = full_2;
  99.             break;
  100.         }
  101.  
  102.         if (dirent_chk (z, full_2))
  103.             dds_add (z);
  104.         strcat(spec, leaf_0);
  105.         /* FALLTHRU */
  106.  
  107.         /*
  108.          * Otherwise, it's a file.
  109.          */
  110.     default:
  111.         if ((fd = creat(spec, 0777)) < 0)
  112.         {
  113.             warn("%s: %s", spec, strerror(errno));
  114.             return;
  115.         }
  116.         close(fd);
  117.         break;
  118.     }
  119.  
  120.     /*
  121.      * Update the display, putting the new entry at the first free-slot.
  122.      *
  123.      * FIXME: should we make this work with V_opt?
  124.      * FIXME: if we create a multilevel directory, we don't add all levels
  125.      */
  126.     if (dirent_chk (z, spec))
  127.         dds_add (z);
  128. }
  129.  
  130. /*
  131.  * Returns nonzero if the file specification ends with a bracket, or the suffix
  132.  * ".DIR"
  133.  */
  134. static
  135. int    looks_like_directory (char *filespec)
  136. {
  137.     char    temp[MAX_PATH];
  138.     size_t    len;
  139.     unsigned status;
  140.     struct    FAB    fab;
  141.     struct    NAM    nam;
  142.     char    rsa    [NAM$C_MAXRSS],    /* resultant string (SYS$SEARCH)*/
  143.         esa    [NAM$C_MAXRSS];    /* expanded string (SYS$PARSE)    */
  144.  
  145.     (void) strucpy(temp, filespec);
  146.     if ((len = strlen(temp)) > 1)
  147.     {
  148.         char    *vers = strrchr(temp, ';');
  149.         if (vers != 0
  150.          && (!strcmp(vers, ";") || !strcmp(vers, ";1")))
  151.         {
  152.              *vers = EOS;
  153.             return looks_like_directory(temp);
  154.         }
  155.         if (temp[len-1] == ']'
  156.          || temp[len-1] == '>')
  157.              return 1;
  158.         if (len > 4)
  159.         {
  160.             if (!strcmp(temp+len-4, ".DIR"))
  161.                 return 2;
  162.         }
  163.     }
  164.  
  165.     /*
  166.      * It looks like a filename. Double-check to ensure that the directory
  167.      * exists.
  168.      */
  169.     rmsinit_fab (&fab, &nam, "", 0);
  170.     fab.fab$l_fna    = temp;
  171.     fab.fab$b_fns    = strlen(temp);
  172.     rmsinit_nam (&nam, rsa, esa);
  173.     if ((status = sys$parse(&fab)) == RMS$_DNF) 
  174.         return 3;
  175.     return 0;
  176. }
  177.