home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 11 Util / 11-Util.zip / xloadimg.zip / xloadimage.4.1 / config.c < prev    next >
C/C++ Source or Header  |  1993-10-28  |  10KB  |  500 lines

  1. /* config.c:
  2.  *
  3.  * functions that deal with the particular configuration.
  4.  *
  5.  * jim frost 10.03.89
  6.  *
  7.  * Copyright 1989, 1990, 1991, 1993 Jim Frost.
  8.  * See included file "copyright.h" for complete copyright information.
  9.  */
  10.  
  11. #include "copyright.h"
  12. #include <ctype.h> /* must here for debugging version under AIX */
  13. #include "xloadimage.h"
  14. #include <X11/Xos.h>
  15. #include <sys/stat.h>
  16. #ifndef VMS
  17. #include <pwd.h>
  18. #endif
  19. #include <errno.h>
  20. #ifndef IS_BSD
  21. #include <unistd.h>
  22. #endif
  23.  
  24. /* SUPPRESS 530 */
  25. /* SUPPRESS 560 */
  26.  
  27. extern int errno;
  28.  
  29. struct filter *Filters = (struct filter *)NULL;
  30.  
  31. static unsigned int  NumPaths= 0;
  32. static unsigned int  NumExts= 0;
  33. static char         *Paths[BUFSIZ];
  34. static char         *Exts[BUFSIZ];
  35. static char         *PathToken= "path";
  36. static char         *ExtToken= "extension";
  37. static char         *FilterToken= "filter";
  38.  
  39. static void addFilter(extension, filter)
  40.      char *extension, *filter;
  41. { struct filter *f, *t;
  42.  
  43.   f= (struct filter *)lmalloc(sizeof(struct filter));
  44.   f->extension= dupString(extension);
  45.   f->filter= dupString(filter);
  46.   f->next= NULL;
  47.   if (Filters) {
  48.     for (t= Filters; t->next; t= t->next)
  49.       /* EMPTY */
  50.       ;
  51.     t->next= f;
  52.   }
  53.   else
  54.     Filters= f;
  55. }
  56.  
  57. enum parse_state {
  58.   parse_void,
  59.   parse_state_token,
  60.   parse_path,
  61.   parse_extension,
  62.   parse_filter_name,
  63.   parse_filter_extension
  64. };
  65.  
  66. /* this function eats up whitespace, incrementing the line number at
  67.  * each newline
  68.  */
  69. static void skip_whitespace(f, linenum)
  70.      FILE *f;
  71.      unsigned int *linenum;
  72. {
  73.   int c;
  74.  
  75.   for (;;) {
  76.     c = fgetc(f);
  77.     switch (c) {
  78.     case EOF:
  79.       return;
  80.     case '\n':
  81.       (*linenum)++;
  82.       /* FALLTHRU */
  83.     case '\r':
  84.     case ' ':
  85.     case '\t':
  86.       continue;
  87.     default:
  88.       ungetc(c, f);
  89.       return;
  90.     }
  91.   }
  92. }
  93.  
  94.  
  95. static void readPathsAndExts(name)
  96.      char *name;
  97. { FILE         *f;
  98.   char          buf[BUFSIZ];
  99.   char          filter_name[BUFSIZ];
  100.   enum parse_state state;
  101.   unsigned int  linenum;
  102.   unsigned int  a;
  103.   int           c;
  104.  
  105.   if (! (f= fopen(name, "r")))
  106.     return;
  107.  
  108.   state = parse_void;
  109.   linenum= 0;
  110.  
  111.   /* this is the token scanner.  i suppose i could have used lex.
  112.    */
  113.   a = 0;
  114.   for (;;) {
  115.     c = fgetc(f);
  116.     if (a >= BUFSIZ) {
  117.       fprintf(stderr, "%s: %d: Buffer overflow (token too long, sorry).\n", name, linenum);
  118.       fclose(f);
  119.       return;
  120.     }
  121.     switch (c) {
  122.     case EOF:
  123.       return;
  124.     case '\n': /* increment line count */
  125.       linenum++;
  126.       /* FALLTHRU */
  127.     case '\r': /* treated as generic white space */
  128.     case ' ':
  129.     case '\t':
  130.       buf[a] = '\0';
  131.       a = 0;
  132.       /* skip forward until next character */
  133.       skip_whitespace(f, &linenum);
  134.       c = fgetc(f);
  135.       if (c == '=') {
  136.     state = parse_state_token;
  137.     skip_whitespace(f, &linenum);
  138.       }
  139.       else if (c != EOF)
  140.     ungetc(c, f);
  141.       break;
  142.     case '=':
  143.       buf[a] = '\0';
  144.       a = 0;
  145.       state = parse_state_token;
  146.       skip_whitespace(f, &linenum);
  147.       break;
  148.     case '#': /* comment */
  149.       for (;;) {
  150.     c = fgetc(f);
  151.     switch (c) { /* eat everything to newline or EOF */
  152.     case '\n':
  153.       linenum++;
  154.     case EOF:
  155.       break;
  156.     default:
  157.       continue;
  158.     }
  159.     break;
  160.       }
  161.  
  162.       /* terminate token
  163.        */
  164.       buf[a] = '\0';
  165.       a = 0;
  166.       break;
  167.     case '"': /* search for end quote */
  168.       while ((c = fgetc(f)) != EOF) {
  169.     if (a >= BUFSIZ) {
  170.       fprintf(stderr, "%s: %d: Buffer overflow while reading string literal.\n",
  171.           name, linenum);
  172.       fclose(f);
  173.       return;
  174.     }
  175.     switch (c) {
  176.     case '"':
  177.       goto done_quote;
  178.     case '\r':
  179.       fprintf(stderr, "%s: %d: Unquoted return character inside string literal.\n",
  180.           name, linenum);
  181.       fclose(f);
  182.       return;
  183.     case '\n':
  184.       fprintf(stderr, "%s: %d: Unquoted newline inside string literal.\n", name,
  185.           linenum);
  186.       fclose(f);
  187.       return;
  188.     case '\\':
  189.       c = fgetc(f);
  190.       if (c == EOF)
  191.         goto done_quote;
  192.       if (c == '\n')
  193.         linenum++;
  194.       /* FALLTHRU */
  195.     default:
  196.       buf[a++] = c;
  197.       continue;
  198.     }
  199.       }
  200.     done_quote:
  201.       continue;
  202.     case '\\': /* literal quote */
  203.       c = fgetc(f);
  204.       if (c == EOF)
  205.     continue;
  206.       if (c == '\n')
  207.     linenum++;
  208.       /* FALLTHRU */
  209.     default:
  210.       buf[a++] = c;
  211.       continue;
  212.     }
  213.  
  214.     /* this disallows nil-string tokens.  thus "" is always ignored.
  215.      */
  216.     if (buf[0] == '\0')
  217.       continue;
  218.  
  219.     /* this handles a token depending on the parser state
  220.      */
  221.     switch (state) {
  222.     case parse_void:
  223.       fprintf(stderr, "%s: %d: Syntax error in defaults file\n", name, linenum);
  224.       fclose(f);
  225.       return;
  226.  
  227.     case parse_state_token:
  228.       if (!strncmp(buf, PathToken, strlen(PathToken)))
  229.     state= parse_path;
  230.       else if (!strncmp(buf, ExtToken, strlen(ExtToken)))
  231.     state= parse_extension;
  232.       else if (!strncmp(buf, FilterToken, strlen(FilterToken)))
  233.     state= parse_filter_name;
  234.       else {
  235.     fprintf(stderr, "%s: %d: Unknown section specifier '%s'.\n",
  236.         name, linenum, buf);
  237.     return;
  238.       }
  239.       break;
  240.     case parse_path:
  241.       if (NumPaths < BUFSIZ - 1)
  242.     Paths[NumPaths++]= expandPath(buf);
  243.       else {
  244.     fprintf(stderr, "%s: %d: Path table overflow\n", name, linenum);
  245.     fclose(f);
  246.     return;
  247.       }
  248.       break;
  249.     case parse_extension:
  250.       if (NumExts < BUFSIZ - 1)
  251.     Exts[NumExts++]= dupString(buf);
  252.       else {
  253.     fprintf(stderr, "%s: %d: Extension table overflow\n", name, linenum);
  254.     fclose(f);
  255.     return;
  256.       }
  257.       break;
  258.     case parse_filter_name: /* name of filter program */
  259.       strcpy(filter_name, buf);
  260.       state= parse_filter_extension;
  261.       break;
  262.     case parse_filter_extension:
  263.       addFilter(buf, filter_name);
  264.       break;
  265.     }
  266.   }
  267. }
  268.  
  269. void loadPathsAndExts()
  270. { static int     havepaths= 0;
  271. #ifndef VMS
  272.   struct passwd *pw;
  273. #endif
  274.   char           buf[BUFSIZ];
  275.  
  276.   if (havepaths)
  277.     return;
  278.   havepaths= 1;
  279.  
  280. #ifdef VMS
  281.   sprintf(buf, "/sys$login:xloadimage.rc");
  282. #else /* !VMS */
  283.   addFilter(".Z", "uncompress -c"); /* std UNIX uncompress */
  284.   addFilter(".gz", "gzip -cd");     /* same, new extension */
  285.   if (! (pw= (struct passwd *)getpwuid(getuid()))) {
  286.     printf("Can't find your password file entry?!?\n");
  287.     return;
  288.   }
  289.   sprintf(buf, "%s/.xloadimagerc", pw->pw_dir);
  290. #endif /* !VMS */
  291.   if (! access(buf, R_OK)) {
  292.     readPathsAndExts(buf);
  293.     return; /* don't read system file if user has one */
  294.   }
  295. #ifdef SYSPATHFILE
  296.   readPathsAndExts(SYSPATHFILE);
  297. #endif
  298. }
  299.  
  300. static int fileIsOk(fullname, sbuf)
  301.      char *fullname;
  302.      struct stat *sbuf;
  303. {
  304.   if ((sbuf->st_mode & S_IFMT) == S_IFDIR) /* is a directory */
  305.     return(0);
  306.   return(access(fullname, R_OK)); /* we can read it */
  307. }
  308.  
  309. /* find an image with paths and extensions from defaults files.  returns
  310.  * -1 if access denied or not found, 0 if ok.
  311.  */
  312.  
  313. int findImage(name, fullname)
  314.      char *name, *fullname;
  315. { unsigned int   p, e;
  316.   struct stat    sbuf;
  317.  
  318.   strcpy(fullname, name);
  319.   if (!strcmp(name, "stdin")) /* stdin is special name */
  320.     return(0);
  321.  
  322.   /* look for name and name with compress extension
  323.    */
  324.   if (! stat(fullname, &sbuf))
  325.       return(fileIsOk(fullname, &sbuf));
  326. #ifndef NO_COMPRESS
  327.   strcat(fullname, ".Z");
  328.   if (! stat(fullname, &sbuf))
  329.       return(fileIsOk(fullname, &sbuf));
  330. #endif
  331.  
  332.   for (p= 0; p < NumPaths; p++) {
  333. #ifdef VMS
  334.     sprintf(fullname, "%s%s", Paths[p], name);
  335. #else
  336.     sprintf(fullname, "%s/%s", Paths[p], name);
  337. #endif
  338.     if (! stat(fullname, &sbuf))
  339.       return(fileIsOk(fullname, &sbuf));
  340. #ifndef NO_COMPRESS
  341.     strcat(fullname, ".Z");
  342.     if (! stat(fullname, &sbuf))
  343. #endif
  344.       return(fileIsOk(fullname, &sbuf));
  345.     for (e= 0; e < NumExts; e++) {
  346. #ifdef VMS
  347.       sprintf(fullname, "%s%s%s", Paths[p], name, Exts[e]);
  348. #else
  349.       sprintf(fullname, "%s/%s%s", Paths[p], name, Exts[e]);
  350. #endif
  351.       if (! stat(fullname, &sbuf))
  352.     return(fileIsOk(fullname, &sbuf));
  353. #ifndef NO_COMPRESS
  354.       strcat(fullname, ".Z");
  355.       if (! stat(fullname, &sbuf))
  356.     return(fileIsOk(fullname, &sbuf));
  357. #endif
  358.     }
  359.   }
  360.  
  361.   for (e= 0; e < NumExts; e++) {
  362.     sprintf(fullname, "%s%s", name, Exts[e]);
  363.     if (! stat(fullname, &sbuf))
  364.       return(fileIsOk(fullname, &sbuf));
  365. #ifndef NO_COMPRESS
  366.     strcat(fullname, ".Z");
  367.     if (! stat(fullname, &sbuf))
  368.       return(fileIsOk(fullname, &sbuf));
  369. #endif
  370.   }
  371.   errno= ENOENT; /* file not found */
  372.   return(-1);
  373. }
  374.  
  375. /* list images along our path
  376.  */
  377.  
  378. void listImages()
  379. { unsigned int a;
  380.   char         buf[BUFSIZ];
  381.  
  382.   if (!NumPaths) {
  383.     printf("No image path\n");
  384.     return;
  385.   }
  386.   for (a= 0; a < NumPaths; a++) {
  387.     printf("%s:\n", Paths[a]);
  388.     fflush(stdout);
  389. #ifdef VMS
  390.     sprintf(buf, "directory %s", Paths[a]);
  391. #else
  392.     sprintf(buf, "ls %s", Paths[a]);
  393. #endif
  394.     if (system(buf) < 0) {
  395. #ifdef VMS
  396.       perror("directory");
  397. #else
  398.       perror("ls");
  399. #endif
  400.       return;
  401.     }
  402.   }
  403.   return;
  404. }
  405.  
  406. void showConfiguration()
  407. { int a;
  408.   struct filter *f;
  409.  
  410.   if (NumPaths) {
  411.     printf("Image path:");
  412.     for (a= 0; a < NumPaths; a++)
  413.       printf(" %s", Paths[a]);
  414.     printf("\n");
  415.   }
  416.   else
  417.     printf("No image path\n");
  418.   if (NumExts) {
  419.     printf("Image extensions:");
  420.     for (a= 0; a < NumExts; a++)
  421.       printf(" %s", Exts[a]);
  422.     printf("\n");
  423.   }
  424.   else
  425.     printf("No image extensions\n");
  426.   if (Filters) {
  427.     printf("Filters:\n");
  428.     for (f= Filters; f; f= f->next)
  429.       printf(" \"%s\" -> \"%s\"\n", f->extension, f->filter);
  430.     printf("\n");
  431.   }
  432.   else
  433.     printf("No filters\n");
  434. }
  435.  
  436. char *expandPath(p)
  437.      char *p;
  438. { char buf1[BUFSIZ], buf2[BUFSIZ];
  439.   int b1, b2, var;
  440.   char *ptr;
  441.  
  442.   char *getenv();
  443.  
  444.   buf1[0] = '\0';
  445.   buf2[0] = '\0';
  446.   b1 = 0;
  447.   b2 = 0;
  448.   var = 0;
  449.  
  450.   while(*p) {
  451.     if(isspace(*p)) break;
  452. #ifndef VMS
  453.     if (*p == '$') var++;
  454. #endif
  455.     else if(*p == '~') {
  456.       buf1[b1] = '\0';
  457.       strcat(buf1, getenv("HOME"));
  458.       b1 = strlen(buf1);
  459.       var = 0;
  460.     }
  461.     else if(*p == '/' || *p == '}') {
  462.       if(var) {
  463.     buf1[b1] = '\0';
  464.     buf2[b2] = '\0';
  465.     strcat(buf1, getenv(buf2));
  466.     b1 = strlen(buf1);
  467.     buf2[0] = '\0';
  468.     b2 = 0;
  469.     var = 0;
  470.       }
  471.       if(*p == '/') {
  472.     buf1[b1] = *p;
  473.     b1++;
  474.       }
  475.     }
  476.     else if(var) {
  477.       if(*p != '{') {
  478.     buf2[b2] = *p;
  479.     b2++;
  480.       }
  481.     }
  482.     else {
  483.       buf1[b1] = *p;
  484.       b1++;
  485.     }
  486.     p++;
  487.   }
  488.  
  489.   buf1[b1] = '\0';
  490.   
  491.   if((b2 = strlen(buf1)) > 0) {
  492.     ptr = (char *)lmalloc((unsigned) b2+1);
  493.     strcpy(ptr, buf1);
  494.     return(ptr);
  495.   }
  496.   else
  497.     return(NULL);
  498.  
  499. }
  500.