home *** CD-ROM | disk | FTP | other *** search
/ Programmer 7500 / MAX_PROGRAMMERS.iso / INFO / C / GLOB.ZIP / CHD.C next >
Encoding:
C/C++ Source or Header  |  1987-07-20  |  6.0 KB  |  214 lines

  1.  
  2. /*
  3.  *    chd.c        change directory
  4.  *            John Plocher
  5.  *
  6.  *    usage:    chd [new directory]
  7.  *
  8.  *        [new directory] may contain wildcards; it may not be ambiguous
  9.  *        If no arguments, use $HOME variable in environment
  10.  *
  11.  *        C:\BIN > set HOME=/usr/plocher
  12.  *        C:\BIN > chd \u*\lo*
  13.  *        C:\USR\LOCAL > chd
  14.  *        C:\USR\PLOCHER >  
  15.  *
  16.  *        uses glob() to expand wildcards in pathname
  17.  *
  18.  *    returns (ERRORLEVEL)
  19.  *
  20.  *        0    No error
  21.  *        1    could not find directory
  22.  *        2    ambiguous pathname
  23.  *        3    directoryname expected, you gave a filename
  24.  *        4    internal error
  25.  *
  26.  *    Change log
  27.  *
  28.  *    Version    Date        Who    Comments
  29.  *    -------    ----        ---    --------
  30.  *    1.00    16-Jan-86    jmp    Initially coded
  31.  *    1.01    21-Jan-86    jmp    Expanded help menu (-?), fixed glob()
  32.  */
  33.  
  34.  
  35. #include <stdio.h>
  36. #include "glob.h"
  37.  
  38. #define VERSION    "1.01 21-Jan-86"
  39. /* #define DEBUG */
  40.  
  41. char *sccsid    = "21-Jan-86 (Plocher) @(#)chd.c    1.01";
  42.  
  43. extern char *strchr();
  44. extern char *getenv();
  45. extern char *strdup();
  46. extern void usage();
  47.  
  48. extern char *filename();
  49. extern char *fixslash();
  50. extern void recover();
  51.  
  52. main(argc, argv)
  53. int argc;
  54. char *argv[];
  55. {
  56.     char **names;    /* array of pointers to names returned by glob() */
  57.     char *progname;    /* name of program (either argv[0] or hardcoded) */
  58.     char *p;        /* temp string pointer */
  59.     char errstring[150];/* for usage() errors */
  60.     char path[127];    /* workspace for getting starting (un-globbed) path */
  61.  
  62.     if (argv[0])    /* if there is something here, use it (DOS 3.xx+) */
  63.         progname = filename(argv[0]);
  64.     else        /* hardcode the program name */
  65.         progname = "chd";
  66.  
  67.     if (argc > 2) {    /* must have less than 2 arguments */
  68.         usage(progname,"Too many arguments");
  69.         exit(1);
  70.     }
  71.     if (argc == 1) {        /* need to get HOME */
  72.         p = getenv("HOME");    /* p == NULL if not found ... */
  73.         if (p != NULL)
  74.             strcpy(path,p);
  75.         else {
  76.             usage(progname,"Environment variable HOME not found\n");
  77.             exit(1);
  78.         }
  79.     } else {        /* we have a pathspec from command line */
  80.         if (argv[1][0] == '-') {    /* if invoked chd -anything, just */
  81.             usage(progname,NULL);    /* explain ourselves */
  82.             exit(0);
  83.         }
  84.         strcpy(path,argv[1]);
  85.     }
  86.  
  87.     fixslash(path);    /* convert all '\'s into '/'s */
  88.  
  89.     names = glob(path);            /* get files which match */
  90.     
  91.     if (names == NULL && globerror == GE_BADPATH) {
  92.         sprintf(errstring,"Path not found: \"%s\"",path);
  93.         usage(progname, errstring);
  94.         recover(names);
  95.         exit(1);
  96.     }
  97.     if ((names == NULL && globerror == GE_AMBIGUOUS) || names[1] != NULL) {
  98.         sprintf(errstring,"Ambiguous pathname \"%s\"",path);
  99.         usage(progname, errstring);
  100.         recover(names);
  101.         exit(2);
  102.     }
  103.     if (chdir(names[0])) {    /* do the actual chdir */
  104.         usage(progname,"You must specify a DIRECTORY path");
  105.         recover(names);
  106.         exit(3);
  107.     }
  108.     if (names == NULL && (globerror == GE_MAXFILES || globerror == GE_NOMEM)) {
  109.         sprintf(errstring,"Internal error: %s",
  110.         globerror == GE_MAXFILES ? "Too many files" : "Out of memory");
  111.         usage(progname, errstring);
  112.         recover(names);
  113.         exit(4);
  114.     }
  115.     recover(names);    /* free memory used by *names[] */
  116.  
  117.     exit(0);        /* no errors */
  118. }
  119.  
  120. /*
  121.  *    usage        tell the workd about this program
  122.  */
  123. void usage(progname, error)
  124. char *progname;
  125. {
  126. fprintf(stderr,"%s version %s by John Plocher on FidoNet 121/90\n",
  127.         progname,VERSION);
  128. if (error)
  129.     fprintf(stderr,"\nERROR: %s\n",error);
  130. else {
  131.  fprintf(stderr,"\n%s - a replacement for MS-DOS's chdir & cd commands\n",
  132.         progname);
  133.  fprintf(stderr,"%s is Copyright 1986 by John Plocher\n\n",progname);
  134.  fprintf(stderr,"%s is released to the NON PROFIT, NON COMMERCIAL public.\n",
  135.         progname);
  136.  fprintf(stderr,"Commercial rights to %s reserved by John Plocher\n", progname);
  137.  fprintf(stderr,"%s has some features which the DOS version lacks:\n",progname);
  138.  fprintf(stderr,"\t1) ALL wildcards (* and ?) are expanded, no matter where\n");
  139.  fprintf(stderr,"\t   they are in the path.\n");
  140.  fprintf(stderr,"\t\tC:\\ >%s \\u*\\p*\\w*\\?\n",progname);
  141.  fprintf(stderr,"\t\tC:\\USR\\PLOCHER\\WORK\\C >\n");
  142.  fprintf(stderr,"\t2) If %s is invoked without arguments, it will try to\n",progname);
  143.  fprintf(stderr,"\t   change to the directory found in the environment\n");
  144.  fprintf(stderr,"\t   variable HOME.\n");
  145.  fprintf(stderr,"\t\tC:\\ >SET HOME=\\usr\\plocher    -or-\n");
  146.  fprintf(stderr,"\t\tC:\\ >SET HOME=\\u*\\p*\n");
  147.  fprintf(stderr,"\t3) If %s fails, it leaves an indication in ERRORLEVEL.\n",progname);
  148.  fprintf(stderr,"\t   This exit code can be tested in batch files:\n");
  149.  fprintf(stderr,"\t    ERRORLEVEL  Meaning\n");
  150.  fprintf(stderr,"\t    ----------  -------\n");
  151.  fprintf(stderr,"\t\t0    No error\n");
  152.  fprintf(stderr,"\t\t1    could not find directory\n");
  153.  fprintf(stderr,"\t\t2    ambiguous pathname\n");
  154.  fprintf(stderr,"\t\t3    directoryname expected, you gave a filename\n");
  155.  fprintf(stderr,"\t\t4    internal error (let me know about this!)\n\n");
  156. }
  157. fprintf(stderr,"usage: %s <directory name>     change to directory\n",progname);
  158. fprintf(stderr,"       %s                      change to HOME\n",progname);
  159. fprintf(stderr,"       %s -?                   help screen\n",progname);
  160. }
  161.  
  162. /*
  163.  *    filename        extract the filename from a pathname
  164.  *                ie C:\usr\plocher\chd.exe results in chd
  165.  */
  166. char *filename(path)
  167. char *path;
  168.  
  169. {
  170.     register char *p, *pd;
  171.  
  172.     p = strchr(path,'\0');    /* work from the back... */
  173.     while (--p != path && *p != ':' && *p != '\\' && *p != '/');
  174.     if (*p == '\\' || *p == '/' || *p == ':')
  175.         p++;
  176.     pd = strchr(p,'.');        /* we don't want the .EXE */
  177.     if (pd != NULL)
  178.         *pd = '\0';
  179.     strlwr(p);
  180.     return (p);
  181. }
  182.  
  183. /*
  184.  *    fixslash    convert all '\'s to '/'s
  185.  */
  186. char *fixslash(s)
  187. char *s;
  188. {
  189.     register int x;
  190.  
  191.     if (s == NULL) return;
  192.     for (x=0; x < strlen(s); x++)
  193.         if (s[x] == '\\')
  194.             s[x] = '/';
  195. }
  196.  
  197.  
  198. /*
  199.  *    recover        free up the space malloc()'d in *names[] by glob()
  200.  */
  201. void recover(names)
  202. char **names;
  203. {
  204.     register int i;
  205.  
  206.     i = 0;
  207.     while (names[i] != (char *)0) {
  208.         free(names[i]);
  209.         i++;
  210.     }
  211.     free(names);
  212. }
  213.  
  214.