/* make_path_info_string WJS Aug 97 */ /* The PATH_INFO environment variable contains 4 fields. */ /* This program accepts a string from the first arg on the */ /* command line. This string consists of up to 3 */ /* labelled fields, each describing one of the first 3 of the 4 */ /* PATH_INFO fields, immediately followed by the 4th PATH_INFO field */ /* (if any) which is NOT labelled. At present, the 4th already */ /* contains labelled information, so the effect will be to accept a */ /* string containing an indefinite amount of labelled information. */ /* Labelled fields MUST precede the unlabelled field. */ /* A labelled field is of the form */ /* label=field */ /* The labelled fields are separated by commas. The assumption is */ /* that no field contains a comma or an equal sign. The labels are */ /* object, protocol, and level. Empty fields are required if the */ /* corresponding field in PATH_INFO is to be empty. (eg, the */ /* the input string would contain "label="). Missing fields mean */ /* that the corresponding field in the existing PATH_INFO should be */ /* used. */ /* The use of equal signs and commas is tied to the assumed format */ /* of the 4th field, again in hopeful anticipation... */ /* */ /* The program writes a "PATH_INFO" string, followed by a newline, */ /* to stdout. The newline can be suppressed by using the -nonewline */ /* switch. */ /* Program exits: */ /* (defined in path_info_routines.h - check there if these */ /* values seem wrong in case they've changed...) */ /* 0 OK */ /* 250 final PATH_INFO string is improper in content or */ /* format, or there was trouble getting dynamic memory */ /* 251 badly formatted input (must be an = in each pair) */ /* 252 duplicated labelled field (among the 1st 3 fields) */ /* 253 level has non-numeric character in it */ /* 254 Bad input switch; > 1 input string */ /* */ /* Example: if make_path_info_string gets */ /* object=//gb1.whoi.edu/test,protocol=html,level=0,dir=xx,info=yy */ /* it will write the string */ /* //gb1.whoi.edu/test.html0{dir=xx,info=yy} */ /* */ /* See the path_info_routines.c file for more information */ #define MAKE_PATH_INFO_ID "make_path_info_string version 1.3 25 Apr 2004" /* 25 Apr 04 v 1.3 WJS */ /* Made this a "major" release to avoid "numbering" problems. */ /* Orig packaging got its version from path_info_routines.c, */ /* which changed faster than its calling routines like this one */ /* W/that program now packaged w/the library, not clear what */ /* the version of THIS package should be... */ /* 11 Feb 04 v 1.3 WJS */ /* Fixes to avoid compiler warnings */ /* [Begin 1.3] */ /* 18 Jul 99 v 1.2a WJS */ /* Allow -no as a synonym for -nonewline */ /* Bug fix: -nonewline output had a concluding \0 as part of it */ /* [Begin 1.2a] */ /* 20 Apr 99 v 1.2 WJS */ /* -nonewline switch */ /* New exit statuses */ /* [Needs path_info_routines.c v 1.2] */ /* [Needs path_info_routines.h v 1.3] */ /* [Begin 1.2] */ /* 17 Sep 97 v 1.1 WJS */ /* Move error defns to .h file */ /* Correct documentation about error returns */ /* [Needs path_info_routines.c v 1.2; .h v 1.2] */ /* [Begin 1.1] */ /* 29 Aug 97 v 1.0 WJS */ /* [Needs path_info_routines.c v 1.2; .h v 1.1] */ /* [Begin 1.0] */ /* Force version string into object files */ char *make_path_info_id = MAKE_PATH_INFO_ID; #include "path_info_routines.h" #include #include #include #define MAX_DEFINED_PAIRS 3 /* object, protocol, level */ /* path_info_routines */ char *make_PATH_INFO_putenv_string(); int main(argc,argv) int argc; char *argv[]; { char *ptr,*end_ptr,*ptr2,*term_char; char *inbuf = NULL; int npairs = 0; /* Init fields to "use what's in existing PATH_INFO" */ char *object_ptr = NULL; char *protocol_ptr = NULL; char *options_ptr = NULL; int level = USE_EXISTING_LEVEL; char *output_terminator = "\n"; int i; for (i = 1; i < argc; i++) if (*argv[i] == '-') { if ( (strcmp(argv[i],"-no") == 0) || (strcmp(argv[i],"-nonewline") == 0) ) output_terminator[0] = '\0'; else { printf ("***ERROR*** illegal switch: %s\n",argv[i]); exit(BAD_ARGS); } } else { if (inbuf != NULL) { printf ("***ERROR*** > 1 input param: %s %s\n",inbuf,argv[i]); exit(BAD_ARGS); } inbuf = argv[i]; } ptr = inbuf; while (ptr != NULL) { /* Need to count pairs in case 4th field contains a duplicate */ /* label to 1st 3. For example, a legit PATH_INFO of */ /* obj.html0{object=doofus} */ /* would have input of */ /* object=obj,protocol=html,level=0,object=doofus */ /* Note problem in future over duplicate labels; note problem */ /* in present code in this case if one of 1st 3 fields missing */ /* obj.html{object=doofus} */ /* would have input of */ /* object=obj,protocol=html,object=doofus */ /* and would produce an error. */ if (++npairs > MAX_DEFINED_PAIRS) { options_ptr = ptr; break; } /* Chop at next comma, if any */ end_ptr = strchr(ptr,PATH_INFO_OPTIONS_SEPARATOR_CHAR); if (end_ptr != NULL) *end_ptr = '\0'; ptr2 = strchr(ptr,PATH_INFO_OPTIONS_DEFN_CHAR); /* Cannot immediately error if = missing, since at present */ /* there is no requirement for 4th field to have =s. Eg */ /* a PATH_INFO of */ /* obj.html{description} */ /* would come from input of */ /* object=obj,protocol=html,description */ /* with legit missing = in 3rd input "pair" */ /* Replace = with '\0' to divide token into label & field */ if (ptr2 != NULL) *(ptr2++) = '\0'; if (strcmp("object",ptr) == 0) { if (object_ptr != NULL) exit(DUP_LABEL); if (ptr2 == NULL) exit(MISSING_EQUAL); object_ptr = ptr2; } else if (strcmp("protocol",ptr) == 0) { if (protocol_ptr != NULL) exit(DUP_LABEL); if (ptr2 == NULL) exit(MISSING_EQUAL); protocol_ptr = ptr2; } else if (strcmp("level",ptr) == 0) { if (level != USE_EXISTING_LEVEL) exit(DUP_LABEL); if (ptr2 == NULL) exit(MISSING_EQUAL); if (*ptr2 == '\0') level = LEVEL_NOT_SPECIFIED; else { level = strtol(ptr2,&term_char,10); if (*term_char != '\0') exit(NON_NUMERIC_LEVEL); } } else { /* Unrecognized label means beginning of options string */ /* We're done parsing; restore = and , then go */ if (ptr2 != NULL) *(--ptr2) = PATH_INFO_OPTIONS_DEFN_CHAR; if (end_ptr != NULL) *end_ptr = PATH_INFO_OPTIONS_SEPARATOR_CHAR; options_ptr = ptr; break; } ptr = (end_ptr == NULL) ? NULL : end_ptr+1; } /* Do it! */ /* "" = don't put "PATH_INFO=" in front of result */ /* NULL means use existing PATH_INFO for defaults */ ptr = make_PATH_INFO_putenv_string ("",NULL,object_ptr,protocol_ptr,level,options_ptr); if (ptr == NULL) exit(BAD_MAKE_PATH_INFO); printf ("%s%s",ptr,output_terminator); exit(0); }