home *** CD-ROM | disk | FTP | other *** search
- #ifndef NO_IDENT
- static char *Id = "$Id: flcrea.c,v 1.2 1995/10/27 23:09:33 tom Exp $";
- #endif
-
- /*
- * Title: flcrea.c
- * Author: T.E.Dickey
- * Created: 27 Oct 1995
- * Last update:
- *
- * Function: This module supports an create-function for "FLIST".
- * No options, no wildcards.
- */
-
- #include <starlet.h>
- #include <stsdef.h>
- #include <rms.h>
-
- #include <stdlib.h>
- #include <stdio.h>
- #include <errno.h>
- #include <string.h> /* 'strerror()', etc. */
- #include <unixio.h> /* 'creat()' */
- #include <unixlib.h> /* 'mkdir()' */
-
- #include "bool.h"
- #include "dclarg.h"
- #include "flist.h" /* 'flist_sysmsg()' */
-
- #include "dds.h"
- #include "dircmd.h"
- #include "dirent.h"
- #include "pathup.h"
- #include "rmsinit.h"
-
- #include "strutils.h"
-
- static int looks_like_directory (char *filespec);
-
- tDIRCMD(flcrea)
- {
- unsigned status;
- FILENT znew, *z = &znew;
- char leaf_0[MAX_PATH];
- char full_1[MAX_PATH];
- char full_2[MAX_PATH];
- char *spec = dclinx (xdcl_, 1, 0);
- int fd;
- int code;
- char *s;
-
- /*
- * If the new item looks like a directory, create a directory.
- */
- switch ((code = looks_like_directory(spec)))
- {
- case 3: /* Make both directory and filename */
- for (s = spec + strlen(spec) - 1; (s - spec) >= 0; s--)
- {
- if (*s == '>' || *s == ']')
- {
- s++;
- break;
- }
- }
- strcpy(leaf_0, s);
- *s = EOS;
- /* FALLTHRU */
- goto bracketed_name;
-
- case 2: /* Translate name to bracketed form */
- status = dirent_chop (z, spec, (struct NAM *)0);
- if (! $VMS_STATUS_SUCCESS(status))
- {
- flist_sysmsg (status);
- return;
- }
- (void)pathdown (spec = full_1, zPATHOF(z), z->fname);
- /*FALLTHRU*/
-
- bracketed_name:
- case 1: /* Make a directory */
- if (mkdir(spec, 0777) < 0)
- {
- warn("%s: %s", spec, strerror(errno));
- return;
- }
- /* Translate the name into a ".dir" form, since that's how
- * it'll get put into the file list
- */
- if (!pathup(full_2, spec))
- {
- warn("%s: unexpected error", spec);
- return;
- }
- if (code != 3)
- {
- spec = full_2;
- break;
- }
-
- if (dirent_chk (z, full_2))
- dds_add (z);
- strcat(spec, leaf_0);
- /* FALLTHRU */
-
- /*
- * Otherwise, it's a file.
- */
- default:
- if ((fd = creat(spec, 0777)) < 0)
- {
- warn("%s: %s", spec, strerror(errno));
- return;
- }
- close(fd);
- break;
- }
-
- /*
- * Update the display, putting the new entry at the first free-slot.
- *
- * FIXME: should we make this work with V_opt?
- * FIXME: if we create a multilevel directory, we don't add all levels
- */
- if (dirent_chk (z, spec))
- dds_add (z);
- }
-
- /*
- * Returns nonzero if the file specification ends with a bracket, or the suffix
- * ".DIR"
- */
- static
- int looks_like_directory (char *filespec)
- {
- char temp[MAX_PATH];
- size_t len;
- unsigned status;
- struct FAB fab;
- struct NAM nam;
- char rsa [NAM$C_MAXRSS], /* resultant string (SYS$SEARCH)*/
- esa [NAM$C_MAXRSS]; /* expanded string (SYS$PARSE) */
-
- (void) strucpy(temp, filespec);
- if ((len = strlen(temp)) > 1)
- {
- char *vers = strrchr(temp, ';');
- if (vers != 0
- && (!strcmp(vers, ";") || !strcmp(vers, ";1")))
- {
- *vers = EOS;
- return looks_like_directory(temp);
- }
- if (temp[len-1] == ']'
- || temp[len-1] == '>')
- return 1;
- if (len > 4)
- {
- if (!strcmp(temp+len-4, ".DIR"))
- return 2;
- }
- }
-
- /*
- * It looks like a filename. Double-check to ensure that the directory
- * exists.
- */
- rmsinit_fab (&fab, &nam, "", 0);
- fab.fab$l_fna = temp;
- fab.fab$b_fns = strlen(temp);
- rmsinit_nam (&nam, rsa, esa);
- if ((status = sys$parse(&fab)) == RMS$_DNF)
- return 3;
- return 0;
- }
-