/* outer_utils.c */ /* Standalone utility programs used by outer. These routines */ /* call no jgofs routines, have no "knowledge" of jgofs system, etc. */ /* They can (and probably should) go into a general library */ /* */ /* char *htmlescape(str) */ /* Takes string destined for stdout in an html environment. */ /* Does necessary conversion so that all characters in the */ /* string are output "as-is"; ie, arranges that no character is */ /* interpreted as "requiring action" by html interpreter */ /* char *trigram(s,replacement_list,trigram_key,len_result) */ /* Replaces selected characters in a string with their hex */ /* equivalents; eg, replace blank with string %20 */ /* char *un_trigram(s,trigram_key,len_result) */ /* Reverses action of trigram */ /* char *outer_utils_return_vers() */ /* Returns version of outer_utils */ /* */ #define OUTER_UTILS_VERSION "outer_utils version 1.0b 20 May 09" /* 20 May 09. WJS */ /* Do not un-trigram a binary 0 */ /* [Begin 1.0b] */ /* 24 Apr 04. WJS */ /* outer_utils_return_vers */ /* [Begin 1.0a] */ /* 4 Dec 98. WJS */ /* [Begin 1.0] */ #include #include #include #include #ifndef VMS #include #endif char *outer_utils_return_vers() /* Routine exists mostly to force .h file version string into this */ /* module, but we could call it if we want. Note string must not be */ /* global or we'll have conflicts if another routine similarly */ /* includes the version string */ { static char version[] = OUTER_UTILS_VERSION; return version; } char *htmlescape(str) char *str; { char *i,*o,*htmlcode,*htmlstuff,*tmp; i=str; htmlstuff=(char *)malloc(strlen("")){ strcpy(htmlstuff,""); *htmlcode='>'; *(htmlcode+1)=0; if((htmlcode=strstr(i,htmlstuff))){ htmlcode +=strlen(htmlstuff); *htmlstuff = *htmlcode; *htmlcode=0; strcpy(o,i); o += strlen(i); i += strlen(i)-1; *htmlcode = *htmlstuff; break; }; }; strcpy(o,"<"); o += 4; break; case '&': strcpy(o,"&"); o += 5; break; case '>': strcpy(o,">"); o += 4; break; default: *(o++) = *i; break; }; i++; }; *o = 0; free (htmlstuff); return tmp; } char *trigram(s,replacement_list,trigram_key,len_result) /* Given a string s, replace selected characters with 3 characters. */ /* The selected characters are supplied by argument replacement_list. */ /* The first replacement character is the supplied trigram key. The */ /* next 2 replacement characters are the hex value of the replace- */ /* ment list character. */ /* The return value is the address of a dynamically allocated */ /* string containing the original string with replacement trigrams. */ /* NULL is returned if the dynamic allocation fails. */ /* If the argument len_result is non-NULL, the length of the */ /* returned string is placed in the address pointed to by len_result */ /* Note that if the trigram key character is present in the input */ /* string, it is user responsibility to be sure that it is followed */ /* by 2 appropriate hex digits (assuming that the output string will */ /* be un-trigrammed at some point) */ /* Characters in the replacement list may not be quoted or */ /* escaped; that is, it is not possible for these characters to */ /* appear in the returned string (unless these characters are hex */ /* digits, in which case they may appear as part of a trigram) */ char *s,*replacement_list,trigram_key; int *len_result; { char *in,*out,*out_str; int i; /* Assume all characters are replaced by trigrams */ out_str = (char *) malloc (3*strlen(s) + 1); if ( (out = out_str) != NULL ) { in = s; while (*in != '\0') { i = strcspn(in,replacement_list); strncpy (out,in,i); out += i; in += i; if (*in != '\0') { *(out++) = trigram_key; sprintf(out,"%02x",*(in++)); out += 2; } } *out = '\0'; } if (len_result != NULL) *len_result = out-out_str; return out_str; } char *un_trigram(s,trigram_key,len_result) /* The string s is searched for the character trigram_key. When */ /* found, the key and the following 2 characters are replaced by a */ /* single ASCII character. This character is the one defined by the */ /* 2 characters following the key, assuming that those 2 characters */ /* are hex digits. */ /* If all trigrams are successfully converted, the return value is */ /* the address of a dynamically allocated string containing the */ /* original string with trigrams replaced. Otherwise, NULL is */ /* returned. */ /* If len_result is non-NULL and all conversions are successful, */ /* the length of the converted string is returned. If there was an */ /* unsuccessful conversion, the offset to the key prefixing the */ /* problem trigram is returned. If an output buffer could not be */ /* allocated, -1 is returned */ /* The trigram key character may not be quoted or escaped; that is */ /* it is not possible for the returned string to include the tri- */ /* gram key unless it itself was present as a trigram in the input */ char *s,trigram_key; int *len_result; { char *in,*out,*out_start; int i; in = s; out_start = (char *) malloc (strlen(s)+1); if ( (out = out_start) == NULL ) { if (len_result != NULL) *len_result = -1; return NULL; } while (*in != '\0') { if (*in == trigram_key) { i = 1000; /* Anything not representable in 2 hex digits */ /* Use scanf instead of strtol so we can confine the trans- */ /* lation to a max of 2 chars. Error in sscanf should not be */ /* possible, but if occurs, won't set i anyway */ if ( isxdigit( *(++in) ) ) if ( isxdigit( *(in+1) ) ) sscanf (in,"%2x",&i); /* == 1000 means could not convert; means error */ /* == 0 would insert a string terminator when there are more */ /* characters to follow. Presents a security risk */ if ((i == 1000) || (i == 0)) { if (len_result != NULL) *len_result = in-s-1; free (out_start); return NULL; } else { in += 2; *(out++) = i; /* Need to worry about sign? Don't think so */ } } else *(out++) = *(in++); } *out = '\0'; if (len_result != NULL) *len_result = out-out_start; return out_start; }