home *** CD-ROM | disk | FTP | other *** search
/ Monster Media 1994 #1 / monster.zip / monster / PROG_C / SNPD9404.ZIP / VFNAME.C < prev    next >
C/C++ Source or Header  |  1994-04-03  |  7KB  |  227 lines

  1. /*
  2. **  VFNAME.C
  3. */
  4.  
  5. #include <stdio.h>
  6. #include <string.h>
  7. #include <conio.h>
  8.  
  9. #ifdef TRUE
  10.  #undef TRUE
  11. #endif
  12. #ifdef FALSE
  13.  #undef FALSE
  14. #endif
  15. #ifdef ERROR
  16.  #undef ERROR
  17. #endif
  18.  
  19. enum LOGICAL {ERROR = -1, SUCCESS, FALSE = 0, TRUE};
  20.  
  21. #if defined(__TURBOC__)
  22.   #include <dir.h>
  23. #endif
  24. #if !defined( MAXFILE )
  25.   #define MAXFILE 9
  26. #endif
  27.  
  28. #define NUL '\0'
  29.  
  30. /*
  31. **  Prototypes
  32. */
  33.  
  34. int valid_fname  (char *fname, int wild_check);
  35.  
  36. /*
  37. **  valid_fname.c
  38. **
  39. **  Verifies whether a filename is valid or invalid without
  40. **  altering the passed filename itself.
  41. **
  42. **  Note that only filenames are validated. Path and drive specs
  43. **  need to be separately validated. See FLN_FIX.C in SNIPPETS.
  44. **
  45. **  Arguments: 2 - fname = a char array MAXFILE long
  46. **                 wild_check: 0 means wildcard use okay
  47. **                             any other value means test for
  48. **                             wildcards which are not acceptable
  49. **
  50. **  Returns:   ERROR   - fname is invalid
  51. **             SUCCESS - fname is valid
  52. **
  53. **  Side effects: none
  54. **
  55. **  Speed: 1) Turbo Profiler rates valid_fname at 0.0004 sec/call
  56. **            on an Intel 80286.
  57. **         2) Token testing from both ends to center yields a slight
  58. **            improvement.
  59. **
  60. **  Notes: Space, ASCII character 32, is a special case. Dos will
  61. **         write a filename or volume label that includes a space.
  62. **         Getting access to that file, afterwards, is not always
  63. **         easy :) For my purposes, space is an invalid filename
  64. **         token. You? You're on your own :)
  65. **
  66. **         Uses strnicmp() and stricmp(), non-ISO/ANSI, but available on
  67. **         all DOS C compilers (MSC, BC++, SC++ WC, etc.)
  68. **
  69. **  Revisions: 1) Dropped str2upper after comment by David Johnson
  70. **                on 07-17-93
  71. **             2) Added [] to token list after comment by Ed
  72. **                Kowalski on 07-17-93
  73. **             3) Added lpt1-lpt3, com1-com4 and clock$ to
  74. **                invalid name list after comment by Ed
  75. **                Kowalski on 07-17-93
  76. **             4) Eliminated double exit points after my own
  77. **                comment to Bob Stout :) on 07/22/1993
  78. **             5) Revisions to detect DOS extension errors on 03/13/94   
  79. **
  80. **  Public domain by Sid Rogers and Bob Stout
  81. **
  82. */
  83.  
  84. int valid_fname(char *fname, int wild_check)
  85. {
  86.       /* invalid filename tokens */
  87.  
  88.       static char invalid_tokens[] = "\0 ,;:|\\/<>\"+=[]*?";
  89.       static int  itoklen = sizeof(invalid_tokens) - 1;
  90.  
  91.       /* invalid file names -- even with extension .xxx */
  92.  
  93.       static char *invalid_3lnam[]={"AUX","CON","PRN","NUL","COM",NULL};
  94.  
  95.       /* other invalid file & directory names */
  96.  
  97.       static char *invalid_4lnam[]={"LPT1","LPT2","LPT3","COM1",
  98.                                     "COM2","COM3","COM4",NULL};
  99.  
  100.       static char *invalid_6lnam = "CLOCK$";
  101.  
  102.       int   num_toks, fl, i, j, k, proceed = 0;
  103.       char *p;
  104.  
  105.       /* Handle the critical stuff first  */
  106.  
  107.       for (i = 0; invalid_3lnam[i]; ++i)
  108.       {
  109.             if (SUCCESS == strnicmp(fname, invalid_3lnam[i], 3))
  110.                   proceed = ERROR;
  111.       }
  112.  
  113.       /* Handle extensions next           */
  114.  
  115.       if (ERROR != proceed && NULL != (p = strchr(fname, '.')))
  116.       {
  117.             if (3 < strlen(p+1) || NULL != strchr(p+1, '.'))
  118.                   proceed = ERROR;
  119.             if (8 < (p - fname))
  120.                   proceed = ERROR;
  121.       }
  122.  
  123.       if (ERROR != proceed)
  124.       {
  125.             if (p)
  126.                   *p = NUL;
  127.  
  128.             for (i = 0; invalid_4lnam[i]; ++i)
  129.             {
  130.                   if (SUCCESS == stricmp(fname, invalid_4lnam[i]))
  131.                         proceed = ERROR;
  132.             }
  133.  
  134.             if (SUCCESS == stricmp(fname, invalid_6lnam))
  135.                   proceed = ERROR;
  136.             if (p)
  137.                   *p = '.';
  138.             else if (8 < strlen(fname))
  139.                   proceed = ERROR;
  140.       }
  141.  
  142.       fl = strlen(fname);
  143.  
  144.       /* process filename for invalid tokens */
  145.  
  146.       if (ERROR != proceed)
  147.       {
  148.             if (wild_check)
  149.                   num_toks = itoklen;                 /* wildcards invalid */
  150.             else  num_toks = itoklen - 2;             /* wildcards ok      */
  151.  
  152.             for (i = -1, j = 0; i < 0 && j < num_toks; j++)
  153.             {
  154.                   for (k = 0; k < fl; k++)
  155.                         if(invalid_tokens[j] == fname[k])
  156.                               i=j;
  157.             }
  158.             if (i >= 0)
  159.                   proceed = ERROR;
  160.       }
  161.       return proceed; /* single exit point */
  162. }
  163.  
  164. #ifdef TEST
  165.  
  166. /*
  167. **  Revised function test - Performs standard tests and then validates
  168. **  filenames passed on the command line.
  169. */
  170.  
  171. main(int argc, char *argv[])
  172. {
  173.       static char *name_test[]= {"aaa","aux","con","prn","nul","lpt1", "lpt2",
  174.                                  "lpt3","com1","com2","com3", "com4","bbbb",
  175.                                  "clock$","com.c", "cccccc",NULL};
  176.  
  177.       static char *token_test[]={"00fname.","01 fname","02fname,", "03fname[",
  178.                                  "04fname;","05fname:", "06fname|","07fname/",
  179.                                  "08fname<", "09fname>","10fname+","11fname=",
  180.                                  "12fname\\","13fname\"","14fname]",
  181.                                  "15fname*", "16fname?","filename", NULL};
  182.  
  183.       char fname[MAXFILE];
  184.       int i;
  185.  
  186.       for (i = 0; name_test[i]; ++i)
  187.       {
  188.             strcpy(fname,name_test[i]);
  189.             printf("%6s is %s\n",fname,
  190.                   valid_fname(fname,0) ? "INvalid" : "Valid");
  191.       }
  192.  
  193.       puts("\nHit a key");
  194.       getch();
  195.  
  196.       puts("\n[Wildcards not allowed]\n");
  197.       for (i = 0; token_test[i]; ++i)
  198.       {
  199.             strcpy(fname,token_test[i]);
  200.             printf("%s is %s\n",fname,
  201.                   valid_fname(fname,1) ? "INvalid" : "Valid");
  202.       }
  203.  
  204.       puts("\nHit a key");
  205.       getch();
  206.  
  207.       puts("\n[Wildcards allowed]\n");
  208.       for (i = 0; token_test[i]; ++i)
  209.       {
  210.             strcpy(fname,token_test[i]);
  211.             printf("%s is %s\n",fname,
  212.                   valid_fname(fname,0) ? "INvalid" : "Valid");
  213.       }
  214.  
  215.       puts("\nHit a key");
  216.       getch();
  217.  
  218.       while (--argc)
  219.       {
  220.             strcpy(fname, *(++argv));
  221.             printf("%s is %s\n",fname,
  222.                   valid_fname(fname,1) ? "INvalid" : "Valid");
  223.       }
  224.       return 0;
  225. }
  226. #endif
  227.