/* File: prtcp.c * * Version: $Revision: 1.2 $ * * Author: Paul Glezen , * * Purpose: Print the contents of an environement variable * with one entry per line and count the number of * characters. Each entry contains * 1.) the order number of the path element * 2.) path element characteristic * 3.) the path element * * Portability: * To port this program to Windows, two changes need * to be made: * * 1. Change the SEPARATOR from ":" to ";" * * 2. Change STRING_COMPARE from strcmp to strcmpi * since Windows is not case sensitive. * * (c) 1998 by Paul Glezen */ #include #include #include #include #include /* Used in stat.h */ #include /* Used for finding file types */ #define SEPARATOR ':' #define STRING_COMPARE strcmp #define MAX_ITEM_LENGTH 200 #define MAX_ITEM_NUMBER 100 #define MAX_TAG_LENGTH 8 void getTag(char* fileName, char* itemTag); short isDup(char* checkString); /* Presently, the strings pointed to by this array are not freed at the end of the program since process clean up will do this. */ static char* items[MAX_ITEM_NUMBER]; static int itemCount = 0; int main(int argc, char* argv[]) { char* path; char* varName; if (argc > 1) varName = argv[1]; else varName = "CLASSPATH"; path = getenv(varName); printf("\n"); if ( path == 0 ) printf("%s is not defined in your environment\n", varName); else { int charCount=0, itemNo=1; char itemTag[MAX_TAG_LENGTH]; char item[MAX_ITEM_LENGTH]; char* c; char* itemPtr; char* cp = calloc(strlen(path)+1, sizeof(char)); strcpy(cp, path); c = cp; itemTag[0] = 0; while ( *c ) { /* -------------------------------------------- Peel off an entry from the path. */ int i = 0; while ( *c != 0 && *c != SEPARATOR && i < MAX_ITEM_LENGTH ) { item[i++] = *c++; } if ( i == MAX_ITEM_LENGTH ) { i--; printf("Error: max length of path reached."); item[i] = 0; while ( *c != 0 && *c != SEPARATOR ) { c++; } } else if ( *c == SEPARATOR ) { c++; } item[i] = 0; /* --------------------------------------------- Examine properties of path entry */ getTag(item, itemTag); /* --------------------------------------------- Print the results for the line */ printf("%3d) %-3s %s\n", itemNo, itemTag, item); itemNo++; } printf("\n\n%s character count: %d\n", varName, c - cp); free(cp); } return 0; } /* ---------------------------------------------------------- Return a tag description based on the type of file the path entry represents. The second parameter is a character array in which to store the result. The tag descriptions are: d directory entry f regular file ne non-existant dup entry is a duplicate of a previous entry blk entry is blank */ #define DIR_FILE "d" #define REG_FILE "f" #define NOT_EXIST "ne" #define DUPLICATE "dup" #define BLANK "blk" void getTag(char* fileName, char* result) { struct stat statBuffer; if ( fileName ) { if ( strlen(fileName) ) { if ( stat(fileName, &statBuffer) != -1 ) { if ( statBuffer.st_mode & S_IFDIR ) { strncpy(result, DIR_FILE, MAX_TAG_LENGTH); } else if ( statBuffer.st_mode & S_IFREG ) { strncpy(result, REG_FILE, MAX_TAG_LENGTH); } } else { if ( errno == ENOENT ) strncpy( result, NOT_EXIST, MAX_TAG_LENGTH); else strncpy( result, "---", MAX_TAG_LENGTH); /* Something funny happened if this last case occurs. */ } if ( isDup(fileName) ) strncpy( result, DUPLICATE, MAX_TAG_LENGTH); } else strncpy( result, BLANK, MAX_TAG_LENGTH); } } /* -------------------------------------------------------------- isDup checks its internal list of strings to determine if it matches one of them. If it doesn't match, it is added to the list. The return value: 1 = match, 0 = no match. */ short isDup(char* checkString) { int i = 0; short result = 0; /* Search until end of list or duplicate. */ while ( i < itemCount && STRING_COMPARE(checkString, items[i++]) ); /* If end of list reached with no dups, then add to list. */ if ( itemCount == 0 || STRING_COMPARE(checkString, items[i-1]) ) { if ( itemCount < MAX_ITEM_NUMBER ) { items[itemCount] = calloc(strlen(checkString)+1, sizeof(char)); if ( items[itemCount] == 0 ) { perror("Memory allocation failure in isDup()"); exit(2); } strcpy(items[itemCount], checkString); itemCount++; } } else result = 1; return result; }