/* ** VFNAME.C */ #include #include #include #ifdef TRUE #undef TRUE #endif #ifdef FALSE #undef FALSE #endif #ifdef ERROR #undef ERROR #endif enum LOGICAL {ERROR = -1, SUCCESS, FALSE = 0, TRUE}; #if defined(__TURBOC__) #include #endif #if !defined( MAXFILE ) #define MAXFILE 9 #endif #define NUL '\0' /* ** Prototypes */ int valid_fname (char *fname, int wild_check); /* ** valid_fname.c ** ** Verifies whether a filename is valid or invalid without ** altering the passed filename itself. ** ** Note that only filenames are validated. Path and drive specs ** need to be separately validated. See FLN_FIX.C in SNIPPETS. ** ** Arguments: 2 - fname = a char array MAXFILE long ** wild_check: 0 means wildcard use okay ** any other value means test for ** wildcards which are not acceptable ** ** Returns: ERROR - fname is invalid ** SUCCESS - fname is valid ** ** Side effects: none ** ** Speed: 1) Turbo Profiler rates valid_fname at 0.0004 sec/call ** on an Intel 80286. ** 2) Token testing from both ends to center yields a slight ** improvement. ** ** Notes: Space, ASCII character 32, is a special case. Dos will ** write a filename or volume label that includes a space. ** Getting access to that file, afterwards, is not always ** easy :) For my purposes, space is an invalid filename ** token. You? You're on your own :) ** ** Uses strnicmp() and stricmp(), non-ISO/ANSI, but available on ** all DOS C compilers (MSC, BC++, SC++ WC, etc.) ** ** Revisions: 1) Dropped str2upper after comment by David Johnson ** on 07-17-93 ** 2) Added [] to token list after comment by Ed ** Kowalski on 07-17-93 ** 3) Added lpt1-lpt3, com1-com4 and clock$ to ** invalid name list after comment by Ed ** Kowalski on 07-17-93 ** 4) Eliminated double exit points after my own ** comment to Bob Stout :) on 07/22/1993 ** 5) Revisions to detect DOS extension errors on 03/13/94 ** ** Public domain by Sid Rogers and Bob Stout ** */ int valid_fname(char *fname, int wild_check) { /* invalid filename tokens */ static char invalid_tokens[] = "\0 ,;:|\\/<>\"+=[]*?"; static int itoklen = sizeof(invalid_tokens) - 1; /* invalid file names -- even with extension .xxx */ static char *invalid_3lnam[]={"AUX","CON","PRN","NUL","COM",NULL}; /* other invalid file & directory names */ static char *invalid_4lnam[]={"LPT1","LPT2","LPT3","COM1", "COM2","COM3","COM4",NULL}; static char *invalid_6lnam = "CLOCK$"; int num_toks, fl, i, j, k, proceed = 0; char *p; /* Handle the critical stuff first */ for (i = 0; invalid_3lnam[i]; ++i) { if (SUCCESS == strnicmp(fname, invalid_3lnam[i], 3)) proceed = ERROR; } /* Handle extensions next */ if (ERROR != proceed && NULL != (p = strchr(fname, '.'))) { if (3 < strlen(p+1) || NULL != strchr(p+1, '.')) proceed = ERROR; if (8 < (p - fname)) proceed = ERROR; } if (ERROR != proceed) { if (p) *p = NUL; for (i = 0; invalid_4lnam[i]; ++i) { if (SUCCESS == stricmp(fname, invalid_4lnam[i])) proceed = ERROR; } if (SUCCESS == stricmp(fname, invalid_6lnam)) proceed = ERROR; if (p) *p = '.'; else if (8 < strlen(fname)) proceed = ERROR; } fl = strlen(fname); /* process filename for invalid tokens */ if (ERROR != proceed) { if (wild_check) num_toks = itoklen; /* wildcards invalid */ else num_toks = itoklen - 2; /* wildcards ok */ for (i = -1, j = 0; i < 0 && j < num_toks; j++) { for (k = 0; k < fl; k++) if(invalid_tokens[j] == fname[k]) i=j; } if (i >= 0) proceed = ERROR; } return proceed; /* single exit point */ } #ifdef TEST /* ** Revised function test - Performs standard tests and then validates ** filenames passed on the command line. */ main(int argc, char *argv[]) { static char *name_test[]= {"aaa","aux","con","prn","nul","lpt1", "lpt2", "lpt3","com1","com2","com3", "com4","bbbb", "clock$","com.c", "cccccc",NULL}; static char *token_test[]={"00fname.","01 fname","02fname,", "03fname[", "04fname;","05fname:", "06fname|","07fname/", "08fname<", "09fname>","10fname+","11fname=", "12fname\\","13fname\"","14fname]", "15fname*", "16fname?","filename", NULL}; char fname[MAXFILE]; int i; for (i = 0; name_test[i]; ++i) { strcpy(fname,name_test[i]); printf("%6s is %s\n",fname, valid_fname(fname,0) ? "INvalid" : "Valid"); } puts("\nHit a key"); getch(); puts("\n[Wildcards not allowed]\n"); for (i = 0; token_test[i]; ++i) { strcpy(fname,token_test[i]); printf("%s is %s\n",fname, valid_fname(fname,1) ? "INvalid" : "Valid"); } puts("\nHit a key"); getch(); puts("\n[Wildcards allowed]\n"); for (i = 0; token_test[i]; ++i) { strcpy(fname,token_test[i]); printf("%s is %s\n",fname, valid_fname(fname,0) ? "INvalid" : "Valid"); } puts("\nHit a key"); getch(); while (--argc) { strcpy(fname, *(++argv)); printf("%s is %s\n",fname, valid_fname(fname,1) ? "INvalid" : "Valid"); } return 0; } #endif