[0001] [0002] [0003] [0004] [0005] [0006] [0007] [0008] [0009] [0010] [0011] [0012] [0013] [0014] [0015] [0016] [0017] [0018] [0019] [0020] [0021] [0022] [0023] [0024] [0025] [0026] [0027] [0028] [0029] [0030] [0031] [0032] [0033] [0034] [0035] [0036] [0037] [0038] [0039] [0040] [0041] [0042] [0043] [0044] [0045] [0046] [0047] [0048] [0049] [0050] [0051] [0052] [0053] [0054] [0055] [0056] [0057] [0058] [0059] [0060] [0061] [0062] [0063] [0064] [0065] [0066] [0067] [0068] [0069] [0070] [0071] [0072] [0073] [0074] [0075] [0076] [0077] [0078] [0079] [0080] [0081] [0082] [0083] [0084] [0085] [0086] [0087] [0088] [0089] [0090] [0091] [0092] [0093] [0094] [0095] [0096] [0097] [0098] [0099] [0100] [0101] [0102] [0103] [0104] [0105] [0106] [0107] [0108] [0109] [0110] [0111] [0112] [0113] [0114] [0115] [0116] [0117] [0118] [0119] [0120] [0121] [0122] [0123] [0124] [0125] [0126] [0127] [0128] [0129] [0130] [0131] [0132] [0133] [0134] [0135] [0136] [0137] [0138] [0139] [0140] [0141] [0142] [0143] [0144] [0145] [0146] [0147] [0148] [0149] [0150] [0151] [0152] [0153] [0154] [0155] [0156] [0157] [0158] [0159] [0160] [0161] [0162] [0163] [0164] [0165] [0166] [0167] [0168] [0169] [0170] [0171] [0172] [0173] [0174] [0175] [0176] [0177] [0178] [0179] [0180] [0181] [0182] [0183] [0184] [0185] [0186] [0187] [0188] [0189] [0190] [0191] [0192] [0193] [0194] [0195] [0196] [0197] [0198] [0199] [0200] [0201] [0202] [0203] [0204] [0205] [0206] [0207] [0208] [0209] [0210] [0211] [0212] [0213] [0214] [0215] [0216] [0217] [0218] [0219] [0220] [0221] [0222] [0223] [0224] [0225] [0226] [0227] [0228] [0229] [0230] [0231] [0232] [0233] [0234] [0235] [0236] [0237] [0238] [0239] [0240] [0241] [0242] [0243] [0244] [0245] [0246] [0247] [0248] [0249] [0250] [0251] [0252] [0253] [0254] [0255] [0256] [0257] [0258] [0259] [0260] [0261] [0262] [0263] [0264] [0265] [0266] [0267] [0268] [0269] [0270] [0271] [0272] [0273] [0274] [0275] [0276] [0277] [0278] [0279] [0280] [0281] [0282] [0283] [0284] [0285] [0286] [0287] [0288] [0289] [0290] [0291] [0292] [0293] [0294] [0295] [0296] [0297] [0298] [0299] [0300] [0301] [0302] [0303] [0304] [0305] [0306] [0307] [0308] [0309] [0310] [0311] [0312] [0313] [0314] [0315] [0316] [0317] [0318] [0319] [0320] [0321] [0322] [0323] [0324] [0325] [0326] [0327] [0328] [0329] [0330] [0331] [0332] [0333] [0334] [0335] [0336] [0337] [0338] [0339] [0340] [0341] [0342] [0343] [0344] [0345] [0346] [0347] [0348] [0349] [0350] [0351] [0352] [0353] [0354] [0355] [0356] [0357] [0358] [0359] [0360] [0361] [0362] [0363] [0364] [0365] [0366] [0367] [0368] [0369] [0370] [0371] [0372] [0373] [0374] [0375] [0376] [0377] [0378] [0379] [0380] [0381] [0382] [0383] [0384] [0385] [0386] [0387] [0388] [0389] [0390] [0391] [0392] [0393] [0394] [0395] [0396] [0397] [0398] [0399] [0400] [0401] [0402] [0403] [0404] [0405] [0406] [0407] [0408] [0409] [0410] [0411] [0412] [0413] [0414] [0415] [0416] [0417] [0418] [0419] [0420] [0421] [0422] [0423] [0424] [0425] [0426] [0427] [0428] [0429] [0430] [0431] [0432] [0433] [0434] [0435] [0436] [0437] [0438] [0439] [0440] [0441] [0442] [0443] [0444] [0445] [0446] [0447] [0448] [0449] [0450] [0451] [0452] [0453] [0454] [0455] [0456] [0457] [0458] [0459] [0460] [0461] [0462] [0463] [0464] [0465] [0466] [0467] [0468] [0469] [0470] [0471] [0472] [0473] [0474] [0475] [0476] [0477] [0478] [0479] [0480] [0481] [0482] [0483] [0484] [0485] [0486] [0487] [0488] [0489] [0490] [0491] [0492] [0493] [0494] [0495] [0496] [0497] [0498] [0499] [0500] [0501] [0502] [0503] [0504] [0505] [0506] [0507] [0508] [0509] [0510] [0511] [0512] [0513] [0514] [0515] [0516] [0517] [0518] [0519] [0520] [0521] [0522] [0523] [0524] [0525] [0526] [0527] [0528] [0529] [0530] [0531] [0532] [0533] [0534] [0535] [0536] [0537] [0538] [0539] [0540] [0541] [0542] [0543] [0544] [0545] [0546] [0547] [0548] [0549] [0550] [0551] [0552] [0553] [0554] [0555] [0556] [0557] [0558] [0559] [0560] [0561] [0562] [0563] [0564] [0565] [0566] [0567] [0568] [0569] [0570] [0571] [0572] [0573] [0574] [0575] [0576] [0577] [0578] [0579] [0580] [0581] [0582] [0583] [0584] [0585] [0586] [0587] [0588] [0589] [0590] [0591] [0592] [0593] [0594] [0595] [0596] [0597] [0598] [0599] [0600] [0601] [0602] [0603] [0604] [0605] [0606] [0607] [0608] [0609] [0610] [0611] [0612] [0613] [0614] [0615] [0616] [0617] [0618] [0619] [0620] [0621] [0622] [0623] [0624] [0625] [0626] [0627] [0628] [0629] [0630] [0631] [0632] [0633] [0634] [0635] [0636] [0637] [0638] [0639] [0640] [0641] [0642] [0643] [0644] [0645] [0646] [0647] [0648] [0649] [0650] [0651] [0652] [0653] [0654] [0655] [0656] [0657] [0658] [0659] [0660] [0661] [0662] [0663] [0664] [0665] [0666] [0667] [0668] [0669] [0670] [0671] [0672] [0673] [0674] [0675] [0676] [0677] [0678] [0679] [0680] [0681] [0682] [0683] [0684] [0685] [0686] [0687] [0688] [0689] [0690] [0691] [0692] [0693] [0694] [0695] [0696] [0697] [0698] [0699] [0700] [0701] [0702] [0703] [0704] [0705] [0706] [0707] [0708] [0709] [0710] [0711] [0712] [0713] [0714] [0715] [0716] [0717] [0718] [0719] [0720] [0721] [0722] [0723] [0724] [0725] [0726] [0727] [0728] [0729] [0730] [0731] [0732] [0733] [0734] [0735] [0736] [0737] [0738] [0739] [0740] [0741] [0742] [0743] [0744] [0745] [0746] [0747] [0748] [0749] [0750] [0751] [0752] [0753] [0754] [0755] [0756] [0757] [0758] [0759] [0760] [0761] [0762] [0763] [0764] [0765] [0766] [0767] [0768] [0769] [0770] [0771] [0772] [0773] [0774] [0775] [0776] [0777] [0778] [0779] [0780] [0781] [0782] [0783] [0784] [0785] [0786] [0787] [0788] [0789] [0790] [0791] [0792] [0793] [0794] [0795] [0796] [0797] [0798] [0799] [0800] [0801] [0802] [0803] [0804] [0805] [0806] [0807] [0808] [0809] [0810] [0811] [0812] [0813] [0814] [0815] [0816] [0817] [0818] [0819] [0820] [0821] [0822] [0823] [0824] [0825] [0826] [0827] [0828] [0829] [0830] [0831] [0832] [0833] [0834] [0835] [0836] [0837] [0838] [0839] [0840] [0841] [0842] [0843] [0844] [0845] [0846] [0847] [0848] [0849] [0850] [0851] [0852] [0853] [0854] [0855] [0856] [0857] [0858] [0859] [0860] [0861] [0862] [0863] [0864] [0865] [0866] [0867] [0868] [0869] [0870] [0871] [0872] [0873] [0874] [0875] [0876] [0877] [0878] [0879] [0880] [0881] [0882] [0883] [0884] [0885] [0886] [0887] [0888] [0889] [0890] [0891] [0892] [0893] [0894] [0895] [0896] [0897] [0898] [0899] [0900] [0901] [0902] [0903] [0904] [0905] [0906] [0907] [0908] [0909] [0910] [0911] [0912] [0913] [0914] [0915] [0916] [0917] [0918] [0919] [0920] [0921] [0922] [0923] [0924] [0925] [0926] [0927] [0928] [0929] [0930] [0931] [0932] [0933] [0934] [0935] [0936] [0937] [0938] [0939] [0940] [0941] [0942] [0943] [0944] [0945] [0946] [0947] [0948] [0949] [0950] [0951] [0952] [0953] [0954] [0955] [0956] [0957] [0958] [0959] [0960]
/* PROGRAM (for OSU DECthreads httpd) Set_DCL_Env.c ** CGI SCRIPT TO SET SYMBOLS FOR DCL ENVIRONMENT. ** ** USAGE: ** $ set noon ** $ say = "write net_link" ** $ crlf = f$fao("!/") ** $ say "<DNETRECMODE>" ! Set implied carriage control (optional) ** $ mcr 'f$parse("SET_DCL_ENV.EXE;",f$environment("PROCEDURE")) ** $ [...] ** Can pass a base symbol prefix as an argument (default is "WWW_"). ** Can pass a form symbol prefix as a second argument to invoke use ** of CGI-SYMBOLS-like symbol names (default is the CERN WWW_KEY_foo ** scheme). ** ** Set the Content-Type in the DCL script, e.g.: ** $ say "Content-Type: text/html", crlf ! CGI header (two crlf's if ** $ [...] <DNETRECMODE> is not set) ** ** or via a printf("Content-Type: text/html\n\n") in an executable, e.g.:) ** $ define sys$output net_link ** $ WWWquery "''database'" "''query'" ** $ deassign sys$output ** $ [...] ** ** Once this program is run by the initial htbin script, any sequence ** of executables or other DCL scripts can be called with sys$output ** assigned to net_link so that their outputs will be sent to the ** client, and they will all have direct access to the full CGI symbol ** environment via DCL symbols (accessible via getenv() calls in C ** programs). ** ** ** AUTHORS: ** FM Foteos Macrides macrides@sci.wfbr.edu ** ** HISTORY: ** 12 Oct 94 FM Written for use with the OSU DECthreads httpd. ** (modification of Dave's CGI_SYMBOLS.C for v1.6 ** and my QueryVMS.c). In addition to setting the ** base CGI symbols via cgi_set_dcl_env(), it casts ** HTTP_ACCEPT into a numbered list and count symbol ** set, coverts POST or GET Form contents into an ** unescaped, numbered KEY (odd is name, even is ** value) and count symbol set, or an ISINDEX query ** into an unescaped, numbered KEY and count symbol ** set, all as in the DCL symbol support for the ** CERN httpd. Note that all symbols are limited ** to 255 characters for DCL, and strings will be ** clipped to that limit if longer. This code does ** not symbolize POST contents other than from Forms. ** If a POST Form submission also has a "?<query>" in ** the RequestURL (rare, but could occur), the KEY ** symbol pairs for the Form content precede those for ** the query. ** This code also fills an "entries" structure with the ** name/value pairs from Forms (like that in QueryVMS.c) ** so you can easily add functions to do something useful ** beyond setting the DCL symbols (to supplement whatever ** you're doing via the DCL command file). As you add ** such functions, you can include getenv() checks for ** symbols set by the DCL command file to regulate their ** implementation. (use the "Check whether we want equal ** signs appended to names." code as a model). ** The WWW_PATH_TRANSLATED symbol is not set to "" by ** cgi_set_dcl_env() if WWW_PATH_INFO is "". This ** script does set it to "", you won't get a DCL error ** if you try to use WWW_PATH_TRANSLATED without first ** checking if WWW_PATH_INFO .nes. "". ** ** Differences from the CERN httpd symbol set: ** =========================================== ** 1) The "WWW_" base and CERN-style form-content ** symbol prefixes can be replaced via a first ** argument for Set_DCL_Env.exe. Any symbols ** set by the calling script for regulating ** Set_DCL_Env.exe should use the alternate ** prefix as well (we'll assume it's "WWW_" in ** the following comments). ** 2) By default, the '=' is not retained on the ends ** of the WWW_KEY_<odd_number> symbols for Form ** content names. (The count is pointed to by ** WWW_KEY_COUNT, equivalently to the CERN httpd.) ** You don't need the equal sign to know that it's ** the name, and it was a pain to deal with when ** formatting text within the script for output ** to the client. The symbol WWW_APPEND_EQUAL_SIGN ** can be made non-NULL by the calling script if you ** do want the equal sign appended. ** 3) WWW_HTTP_ACCEPT points to the full, comma ** separated list of accepted MIME types, not to ** the count of WWW_HTTP_ACCEPT_<number> symbols ** as does the CERN httpd. The count is pointed to ** instead by WWW_HTTP_ACCEPT_COUNT. The comma ** separated list is likely to be clipped at 255 ** characters (so you'd be unwise to parse it rather ** than checking the numbered list via a DCL loop, ** but cgi_set_dcl_env() sets WWW_HTTP_ACCEPT to ** that list, and so I left it that way. You can ** also search the accepted MIME types by using ** <DNETHDR>, but that's more work and overhead ** than looping through this numbered list. ** 4) I didn't include WWW_REFERER_URL, because you ** can get it as WWW_HTTP_REFERER. ** 5) The WWW_HTTP_ACCEPT_LANGUAGE symbol is a comma ** separated list, as for the CERN server, but is ** cast to a WWW_HTTP_ACCEPT_LANGUAGE_COUNT and ** WWW_HTTP_ACCEPT_LANGUAGE_<num> symbol set as ** well. ** ** 12 Mar 95 FM Added multi-line TEXTAREA handling, identical to ** that for the CERN httpd. ** ** 13 Mar 95 FM Added option to process POST or GET Form content ** equivalently to the v1.7a CGI_SYMBOLS.c, if ** Set_DCL_Env.exe is invoked with a second ** (Form prefix) argument. The first argument ** must be the base prefix (normally "WWW_"). ** See comments in do_cgi_form_env() concerning ** the limitations of this symbolizing scheme, ** but it's easier to use with simple forms. ** In addition to CGI_SYMBOL.c's foo_FLD_name ** symbols and foo_FIELDS list, this version ** includes foo_FLD_COUNT and foo_FIELDS_COUNT ** symbols (for error checking). ** ** 18 Mar 95 FM Added check for WWW_APPEND_EQUAL_SIGN (replace the ** "WWW_" with the alternate symbol prefix, if one ** has been passed as an argument). ** ** 22 Apr 95 FM Added WWW_HTTP_ACCEPT_LANGUAGE symbol and a ** WWW_HTTP_ACCEPT_LANGUAGE_COUNT and itemized ** WWW_HTTP_ACCEPT_LANGUAGE_<num> symbol set. ** ** 23 Apr 95 FM Added WWW_AUTH_TYPE handling (is set to the ** authentication type, e.g., "Basic", or to "" if ** the script was not invoked with authentication. ** Added code to set the WWW_PATH_TRANSLATED symbol ** to "" if no translation is present. ** ** 28 Apr 95 FM Added code to set WWW_REMOTE_IDENT and ** WWW_REMOTE_USER to "" if no translation ** is present. ** ** 20 May 95 FM Treat CRLF, lone LF or lone CR as 'newline' (LF) ** when unescaping. ** ** 14 Jan 96 FM Modified do_cgi_form_env() emulation of CGI_Symbols.c ** to create a comma-separated list of VALUEs for fields ** which have the same NAME (as in SELECTs with the ** MULTIPLE attribute set). ** BUGS: ** */ #include <stdio.h> #include <stdlib.h> #include <unixlib.h> #include <ctype.h> #include <stdarg.h> #include <descrip.h> #include <libclidef.h> #include <string.h> #include "cgilib.h" #include "scriptlib.h" #define MAX_ENTRIES 1000 /* Maximum name/value pairs to handle */ #define MAX_PREFIX_LEN 100 /* Maximum prefix length (default is "WWW_" */ typedef struct { /* Structure for holding name/value pairs */ char *name; char *val; } entry; static entry entries[MAX_ENTRIES]; static char prefix[256]; static int prefix_len=0; static char Fprefix[256]; static int Fprefix_len=0; static char AcceptCount[20]; static char KeyCount[20]; static void getword(char *word, char *line, char stop); static char *makeword(char *line, char stop); static char *fmakeword(FILE *f, char stop, int *len); static char x2c(char *what); static void unescape_url(char *url); static void plustospace(char *str); static int strcasecomp(char *a, char *b); static int strncasecomp(char *a, char *b, int); static void do_dcl_form_env(int m); static void do_cgi_form_env(int m); int main(int argc, char *argv[]) { register int x, m=0, line; char *cp, *cp1, *METHOD, *ACCEPT; int status, cl, len; unsigned char append_equal_sign=0; FILE *contentf; int i, LIB$GET_SYMBOL(), LIB$SET_SYMBOL(), length, virtual_argc; int table = LIB$K_CLI_LOCAL_SYM; int count=0; char *virtual_argv[4]; char param_name[4], param_value[256], symname[256], symvalue[256]; $DESCRIPTOR(pname,""); $DESCRIPTOR(pvalue,""); $DESCRIPTOR(symbol,""); $DESCRIPTOR(value,""); symbol.dsc$a_pointer = symname; /* * Check for invalid invocation */ if ( argc > 3 ) { printf( "Too many arguments, this program must be run from a DCL script\n"); exit (20); } /* * Build dummy argument list from P1 through P3 to get the values WWWEXEC * passed to the script. */ virtual_argc = 4; virtual_argv[0] = argv[0]; /* for lack of anything better! */ pname.dsc$w_length = 2; pname.dsc$a_pointer = param_name; pvalue.dsc$w_length = sizeof(param_value)-1; pvalue.dsc$a_pointer = param_value; for ( i = 1; i < virtual_argc; i++ ) { sprintf ( param_name, "P%d", i ); length = 0; status = LIB$GET_SYMBOL ( &pname, &pvalue, &length ); if ( (status&1) == 1 ) { /* * Allocate new buffer to hold value. */ virtual_argv[i] = malloc ( length+1 ); param_value[length] = '\0'; strcpy ( virtual_argv[i], param_value ); } else virtual_argv[i] = ""; } /* * Load the base CGI environment for conversion to DCL symbols. */ status = cgi_init ( virtual_argc, virtual_argv ); if ( (status&1) == 0 ) return status; /* * Get the CGI symbol prefix and set the basic symbols. */ strncpy( prefix, ((argc > 1) ? argv[1] : "WWW_"), MAX_PREFIX_LEN ); prefix[MAX_PREFIX_LEN] = '\0'; prefix_len = strlen ( prefix ); cgi_set_dcl_env ( prefix ); /* * Check if CGI_SYMBOLS-like parsing of form input is wanted. */ strncpy( Fprefix, ((argc > 2) ? argv[2] : ""), MAX_PREFIX_LEN); Fprefix[MAX_PREFIX_LEN] = '\0'; Fprefix_len = strlen ( Fprefix ); /* * Recast HTTP_ACCEPT to a numbered symbol list. */ if ( (ACCEPT=cgi_info("HTTP_ACCEPT")) != NULL && *ACCEPT != '\0' ) { count = 0; while ( (cp=strchr(ACCEPT, ',')) != NULL ) { *(cp++) = '\0'; while ( isspace(*ACCEPT) ) ACCEPT++; sprintf( symname, "%sHTTP_ACCEPT_%d", prefix, ++count ); symbol.dsc$w_length = strlen( symname ); value.dsc$a_pointer = ACCEPT; value.dsc$w_length = strlen( ACCEPT ); if ( value.dsc$w_length > 255 ) value.dsc$w_length = 255; status = LIB$SET_SYMBOL ( &symbol, &value, &table ); if ( (status&1) == 0 ) fprintf(stderr, "Error defining %s symbol. status: %d\n", symname, status ); ACCEPT = cp; } if (*ACCEPT != '\0') { while ( isspace(*ACCEPT) ) ACCEPT++; sprintf( symname, "%sHTTP_ACCEPT_%d", prefix, ++count ); symbol.dsc$w_length = strlen( symname ); value.dsc$a_pointer = ACCEPT; value.dsc$w_length = strlen( ACCEPT ); if ( value.dsc$w_length > 255 ) value.dsc$w_length = 255; status = LIB$SET_SYMBOL ( &symbol, &value, &table ); if ( (status&1) == 0 ) fprintf(stderr, "Error defining %s symbol. status: %d\n", symname, status ); } } /* * Set the ACCEPT count. */ sprintf( symname, "%sHTTP_ACCEPT_COUNT", prefix ); symbol.dsc$w_length = strlen( symname ); sprintf( AcceptCount, "%d", count ); value.dsc$a_pointer = AcceptCount; value.dsc$w_length = strlen ( AcceptCount ); status = LIB$SET_SYMBOL ( &symbol, &value, &table ); if ( (status&1) == 0 ) fprintf(stderr, "Error defining %s symbol. status: %d\n", symname, status ); count = 0; /* * Recast HTTP_ACCEPT_LANGUAGE to a numbered symbol list. */ if ( (ACCEPT=cgi_info("HTTP_ACCEPT_LANGUAGE")) != NULL && *ACCEPT != '\0' ) { count = 0; while ( (cp=strchr(ACCEPT, ',')) != NULL ) { *(cp++) = '\0'; while ( isspace(*ACCEPT) ) ACCEPT++; sprintf( symname, "%sHTTP_ACCEPT_LANGUAGE_%d", prefix, ++count ); symbol.dsc$w_length = strlen( symname ); value.dsc$a_pointer = ACCEPT; value.dsc$w_length = strlen( ACCEPT ); if ( value.dsc$w_length > 255 ) value.dsc$w_length = 255; status = LIB$SET_SYMBOL ( &symbol, &value, &table ); if ( (status&1) == 0 ) fprintf(stderr, "Error defining %s symbol. status: %d\n", symname, status ); ACCEPT = cp; } if (*ACCEPT != '\0') { while ( isspace(*ACCEPT) ) ACCEPT++; sprintf( symname, "%sHTTP_ACCEPT_LANGUAGE_%d", prefix, ++count ); symbol.dsc$w_length = strlen( symname ); value.dsc$a_pointer = ACCEPT; value.dsc$w_length = strlen( ACCEPT ); if ( value.dsc$w_length > 255 ) value.dsc$w_length = 255; status = LIB$SET_SYMBOL ( &symbol, &value, &table ); if ( (status&1) == 0 ) fprintf(stderr, "Error defining %s symbol. status: %d\n", symname, status ); } } /* * Set the ACCEPT_LANGUAGE count. */ sprintf( symname, "%sHTTP_ACCEPT_LANGUAGE_COUNT", prefix ); symbol.dsc$w_length = strlen( symname ); sprintf( AcceptCount, "%d", count ); value.dsc$a_pointer = AcceptCount; value.dsc$w_length = strlen ( AcceptCount ); status = LIB$SET_SYMBOL ( &symbol, &value, &table ); if ( (status&1) == 0 ) fprintf(stderr, "Error defining %s symbol. status: %d\n", symname, status ); count = 0; /* * Pick up CGI symbols which the cgilib/scriptlib * doesn't presently handle properly. */ sprintf( symname, "%sAUTH_TYPE", prefix ); if ( getenv( symname ) == NULL ) { sprintf( symname, "%sHTTP_AUTHORIZATION", prefix ); if ( ( cp = getenv( symname ) ) != NULL ) { if ( ( cp1 = strchr( cp, ' ' ) ) != NULL ) *cp1 = '\0'; if ( strlen( cp ) > 255 ) cp[255] = '\0'; } else cp = ""; sprintf( symname, "%sAUTH_TYPE", prefix ); symbol.dsc$w_length = strlen( symname ); sprintf( symvalue, "%s", cp ); value.dsc$a_pointer = symvalue; value.dsc$w_length = strlen ( symvalue ); status = LIB$SET_SYMBOL ( &symbol, &value, &table ); if ( (status&1) == 0 ) fprintf(stderr, "Error defining %s symbol. status: %d\n", symname, status ); } sprintf( symname, "%sPATH_TRANSLATED", prefix ); if ( getenv( symname ) == NULL ) { symbol.dsc$w_length = strlen( symname ); symvalue[0] = '\0'; value.dsc$a_pointer = symvalue; value.dsc$w_length = 0; status = LIB$SET_SYMBOL ( &symbol, &value, &table ); if ( (status&1) == 0 ) fprintf(stderr, "Error defining %s symbol. status: %d\n", symname, status ); } sprintf( symname, "%sREMOTE_IDENT", prefix ); if ( getenv( symname ) == NULL ) { symbol.dsc$w_length = strlen( symname ); symvalue[0] = '\0'; value.dsc$a_pointer = symvalue; value.dsc$w_length = 0; status = LIB$SET_SYMBOL ( &symbol, &value, &table ); if ( (status&1) == 0 ) fprintf(stderr, "Error defining %s symbol. status: %d\n", symname, status ); } sprintf( symname, "%sREMOTE_USER", prefix ); if ( getenv( symname ) == NULL ) { symbol.dsc$w_length = strlen( symname ); symvalue[0] = '\0'; value.dsc$a_pointer = symvalue; value.dsc$w_length = 0; status = LIB$SET_SYMBOL ( &symbol, &value, &table ); if ( (status&1) == 0 ) fprintf(stderr, "Error defining %s symbol. status: %d\n", symname, status ); } /* * Check for Form content. */ if ( (METHOD=cgi_info("REQUEST_METHOD")) != NULL) { /* * Check whether we want equal signs appended to names. */ sprintf( symname, "%sAPPEND_EQUAL_SIGN", prefix ); if ( getenv( symname ) != NULL ) append_equal_sign = 1; if ( 0==strcasecomp( METHOD, "POST" ) && (cp=cgi_info( "CONTENT_TYPE" )) != NULL && 0==strcasecomp(cp,"application/x-www-form-urlencoded") ) { /* * It's a Form with METHOD="POST". */ cl = atoi( (cp=cgi_info("CONTENT_LENGTH")) ? cp : "0" ); if ( cl && (contentf = cgi_content_file()) ) { /* * We have POST content. */ for(x = 0; cl && (!feof(contentf) && x < MAX_ENTRIES); x++) { entries[x].val = fmakeword(contentf, '&', &cl); plustospace(entries[x].val); unescape_url(entries[x].val); entries[x].name = makeword(entries[x].val,'='); if (append_equal_sign) strcat(entries[x].name, "="); m++; } if ( *Fprefix == '\0' ) { /* * Default CERN-style symbols wanted. */ do_dcl_form_env(m); count = (2 * m); } else { /* * OSU CGI_SYMBOLS-style symbols wanted. */ do_cgi_form_env(m); count = 0; } } } else if ( 0==strcasecomp( METHOD, "GET" ) && (cp=cgi_info("QUERY_STRING")) != NULL && *cp != '\0' && strchr( cp, '=') != NULL ) { /* * It's a Form with METHOD="GET" and we have content. */ for(x=0; cp[0] != '\0' && x < MAX_ENTRIES; x++) { len = strlen(cp) + 1; if (cp1=strchr(cp, '&')) len -= strlen(cp1); entries[x].val = (char *) malloc(sizeof(char) * len); getword(entries[x].val, cp, '&'); plustospace(entries[x].val); unescape_url(entries[x].val); entries[x].name = makeword(entries[x].val,'='); if (append_equal_sign) strcat(entries[x].name, "="); m++; } if ( *Fprefix == '\0' ) { /* * Default CERN-style symbols wanted. */ do_dcl_form_env(m); count = (2 * m); } else { /* * OSU CGI_SYMBOLS-style symbols wanted. */ do_cgi_form_env(m); count = 0; } } else if ( *Fprefix != '\0' ) { /* * Output foo_FIELDS_COUNT and foo_FLD_COUNT symbols * with zero values. */ sprintf( symname, "%sFIELDS_COUNT", Fprefix ); symbol.dsc$w_length = strlen( symname ); strcpy(KeyCount, "0"); value.dsc$a_pointer = KeyCount; value.dsc$w_length = 1; status = LIB$SET_SYMBOL ( &symbol, &value, &table ); if ( (status&1) == 0 ) fprintf(stderr, "Error defining %s symbol. status: %d\n", symname, status ); sprintf( symname, "%sFLD_COUNT", Fprefix ); symbol.dsc$w_length = strlen( symname ); strcpy(KeyCount, "0"); value.dsc$a_pointer = KeyCount; value.dsc$w_length = 1; status = LIB$SET_SYMBOL ( &symbol, &value, &table ); if ( (status&1) == 0 ) fprintf(stderr, "Error defining %s symbol. status: %d\n", symname, status ); } } /* * Check for an ISINDEX query. */ if ( (cp=cgi_info( "QUERY_STRING" )) != NULL && *cp != '\0' && strchr( cp, '=' ) == NULL ) { /* * Check for a + separated set of terms. */ char *query = cp; while ( (cp=strchr(query, '+')) != NULL ) { *(cp++) = '\0'; unescape_url(query); sprintf( symname, "%sKEY_%d", prefix, ++count ); symbol.dsc$w_length = strlen( symname ); value.dsc$a_pointer = query; value.dsc$w_length = strlen (query); if ( value.dsc$w_length > 255 ) value.dsc$w_length = 255; status = LIB$SET_SYMBOL ( &symbol, &value, &table ); if ( (status&1) == 0 ) fprintf(stderr, "Error defining %s symbol. status: %d\n", symname, status ); query = cp; } /* * Do the first term if its the only, or the last term. */ if ( *query != '\0' ) { unescape_url(query); sprintf( symname, "%sKEY_%d", prefix, ++count ); symbol.dsc$w_length = strlen( symname ); value.dsc$a_pointer = query; value.dsc$w_length = strlen (query); if ( value.dsc$w_length > 255 ) value.dsc$w_length = 255; status = LIB$SET_SYMBOL ( &symbol, &value, &table ); if ( (status&1) == 0 ) fprintf(stderr, "Error defining %s symbol. status: %d\n", symname, status ); } } /* * Set the KEY count. */ sprintf( symname, "%sKEY_COUNT", prefix ); symbol.dsc$w_length = strlen( symname ); sprintf(KeyCount, "%d", count); value.dsc$a_pointer = KeyCount; value.dsc$w_length = strlen ( KeyCount ); status = LIB$SET_SYMBOL ( &symbol, &value, &table ); if ( (status&1) == 0 ) fprintf(stderr, "Error defining %s symbol. status: %d\n", symname, status ); /* * Add any supplementary function calls here. */ /* * Return control to the DCL command file. */ return (1); } /* main */ static void getword(char *word, char *line, char stop) { int x = 0,y; for(x=0; ((line[x] != '\0') && (line[x] != stop)); x++) word[x] = line[x]; word[x] = '\0'; if(line[x]) ++x; y=0; while(line[y++] = line[x++]); return; } static char *makeword(char *line, char stop) { int x = 0,y; char *word = (char *) malloc(sizeof(char) * (strlen(line) + 1)); for(x=0;((line[x]) && (line[x] != stop));x++) word[x] = line[x]; word[x] = '\0'; if(line[x]) ++x; y=0; while(line[y++] = line[x++]); return word; } static char *fmakeword(FILE *f, char stop, int *cl) { int wsize; char *word; int ll; wsize = 96; ll=0; word = (char *) malloc(sizeof(char) * (wsize + 1)); while(1) { word[ll] = (char)fgetc(f); if(ll==wsize) { word[ll+1] = '\0'; wsize+=1024; word = (char *)realloc(word,sizeof(char)*(wsize+1)); } --(*cl); if((word[ll] == stop) || (feof(f)) || (!(*cl))) { if(word[ll] != stop) ll++; word[ll] = '\0'; return word; } ++ll; } } static char x2c(char *what) { register char digit; digit = (what[0] >= 'A' ? ((what[0] & 0xdf) - 'A')+10 : (what[0] - '0')); digit *= 16; digit += (what[1] >= 'A' ? ((what[1] & 0xdf) - 'A')+10 : (what[1] - '0')); return(digit); } static void unescape_url(char *url) { register int x,y; for(x=0,y=0;url[y];++x,++y) { if((url[x] = url[y]) == '%') { url[x] = x2c(&url[y+1]); y+=2; if(url[x] == '\r') { if(url[y] == '%' && x2c(&url[y+1]) == '\n') /* Ignore the CR in CRLFs */ x--; else /* Convert lone CR to LF */ url[x] = '\n'; } } } url[x] = '\0'; } static void plustospace(char *str) { register int x; for(x=0;str[x];x++) if(str[x] == '+') str[x] = ' '; } static int strcasecomp(char *a, char *b) { char *p = a; char *q = b; for(p=a, q=b; *p && *q; p++, q++) { int diff = tolower(*p) - tolower(*q); if (diff) return diff; } if (*p) return 1; /* p was longer than q */ if (*q) return -1; /* p was shorter than q */ return 0; /* Exact match */ } static int strncasecomp(char *a, char *b, int n) { char *p = a; char *q = b; for(p=a, q=b;; p++, q++) { int diff; if (p == a+n) return 0; /* Match up to n characters */ if (!(*p && *q)) return *p - *q; diff = tolower(*p) - tolower(*q); if (diff) return diff; } } static void do_dcl_form_env(int m) { int i, count, status, length, table, LIB$SET_SYMBOL(); $DESCRIPTOR(symbol,""); $DESCRIPTOR(value,""); char symname[256]; register int x; symbol.dsc$a_pointer = symname; /* * Define local symbols to be used by calling script. */ table = LIB$K_CLI_LOCAL_SYM; for ( count = x = 0; x < m; x++ ) { /* * Set key for name. */ sprintf( symname, "%sKEY_%d", prefix, ++count ); symbol.dsc$w_length = strlen( symname ); value.dsc$a_pointer = entries[x].name; value.dsc$w_length = strlen ( entries[x].name ); if ( value.dsc$w_length > 255 ) value.dsc$w_length = 255; status = LIB$SET_SYMBOL ( &symbol, &value, &table ); if ( (status&1) == 0 ) fprintf(stderr, "Error defining %s symbol. status: %d\n", symname, status ); /* * Set key(s) for value. */ if ( strchr( entries[x].val, '\n' ) == NULL ) { /* * Value is a simple string. */ sprintf( symname, "%sKEY_%d", prefix, ++count ); symbol.dsc$w_length = strlen( symname ); value.dsc$a_pointer = entries[x].val; value.dsc$w_length = strlen ( entries[x].val ); if ( value.dsc$w_length > 255 ) value.dsc$w_length = 255; status = LIB$SET_SYMBOL ( &symbol, &value, &table ); if ( (status&1) == 0 ) fprintf(stderr, "Error defining %s symbol. status: %d\n", symname, status ); } else { /* * Value is a multi-line TEXTAREA. */ int line = 0; char *newline; char *cp = entries[x].val; ++count; while ( (newline=strchr( cp, '\n' )) != NULL ) { /* * Get all the lines preceding newlines. */ *newline = '\0'; sprintf( symname, "%sKEY_%d_%d", prefix, count, ++line ); symbol.dsc$w_length = strlen( symname ); value.dsc$a_pointer = cp; value.dsc$w_length = strlen ( cp ); if ( value.dsc$w_length > 255 ) value.dsc$w_length = 255; status = LIB$SET_SYMBOL ( &symbol, &value, &table ); if ( (status&1) == 0 ) fprintf(stderr, "Error defining %s symbol. status: %d\n", symname, status ); cp = (newline + 1); } if ( *cp != '\0' ) { /* * Get the last line if there wasn't a terminal newline. */ sprintf( symname, "%sKEY_%d_%d", prefix, count, ++line ); symbol.dsc$w_length = strlen( symname ); value.dsc$a_pointer = cp; value.dsc$w_length = strlen ( cp ); if ( value.dsc$w_length > 255 ) value.dsc$w_length = 255; status = LIB$SET_SYMBOL ( &symbol, &value, &table ); if ( (status&1) == 0 ) fprintf(stderr, "Error defining %s symbol. status: %d\n", symname, status ); } /* * Set the line count for this key. */ sprintf( symname, "%sKEY_%d_COUNT", prefix, count); symbol.dsc$w_length = strlen( symname ); sprintf(KeyCount, "%d", line); value.dsc$a_pointer = KeyCount; value.dsc$w_length = strlen ( KeyCount ); status = LIB$SET_SYMBOL ( &symbol, &value, &table ); if ( (status&1) == 0 ) fprintf(stderr, "Error defining %s symbol. status: %d\n", symname, status ); } } return; } static void do_cgi_form_env (int m) { int i, j, FLDCount, FIELDSCount, status, length, table, LIB$SET_SYMBOL(); $DESCRIPTOR(symbol,""); $DESCRIPTOR(value,""); char symname[256], sym_list[256], temp[256]; char *cp; register int x; symbol.dsc$a_pointer = symname; /* * Initilize our comma-separated list of names and counters. */ for (i = 0; i < 256; i++) sym_list[i] = '\0'; length = 0; FLDCount = 0; FIELDSCount = 0; /* * Define local symbols to be used by calling script. */ table = LIB$K_CLI_LOCAL_SYM; /* * Set the foo_FLD_name symbol values. * * Note that with this design, multi-line TEXTAREA values are * almost certain to be trunctated. */ sprintf( symname, "%sFLD_", Fprefix ); symname[255] = '\0'; for ( x = 0; x < m; x++ ) { strncpy( (char *)&symname[Fprefix_len], entries[x].name, (255 - Fprefix_len) ); /* * Force field names uppercase and convert any dashes to underscores. */ for ( i = Fprefix_len; symname[i] != '\0'; i++ ) { symname[i] = toupper( symname[i] ); if (symname[i] == '-') symname[i] = '_'; } symbol.dsc$w_length = strlen( symname ); /* * Check if we already have the name, and if not, set the * new name=value pair, otherwise, append the value to the * existing one as a comma-separated list. */ i = 0; while ( i < x && strcmp( entries[i].name, entries[x].name ) ) i++; if ( i >= x ) { /* * Set the new pair; */ value.dsc$a_pointer = entries[x].val; value.dsc$w_length = strlen ( entries[x].val ); if ( value.dsc$w_length > 255 ) value.dsc$w_length = 255; status = LIB$SET_SYMBOL ( &symbol, &value, &table ); if ( (status&1) == 0 ) { fprintf( stderr, "Error defining %s symbol. status: %d\n", symname, status ); } else { FLDCount++; /* * Create or extend a comma-separated list * of form field names. * * Note that this list is likely to be * trunctated for a large form. */ j = strlen( entries[x].name ); if ( (length + j + (sym_list[0] ? 2 : 1)) < 256 ) { if ( sym_list[0] ) { strcat( sym_list, "," ); length++; } strcat( sym_list, entries[x].name ); length += j; FIELDSCount++; } } } else { /* * Append the current value to the previous value * as a comma separated list. */ cp = getenv( symname ); j = strlen( entries[x].val ) + (cp ? strlen( cp ) : 256) + 2; if ( j < 256 ) { strcpy( temp, cp ); strcat( temp, "," ); strcat( temp, entries[x].val ); value.dsc$a_pointer = temp; value.dsc$w_length = strlen ( temp ); status = LIB$SET_SYMBOL ( &symbol, &value, &table ); if ( (status&1) == 0 ) { fprintf( stderr, "Error redefining %s symbol. status: %d\n", symname, status ); } } else { fprintf( stderr, "Error extending %s symbol. status: %d\n", symname, status ); } } } /* * Set a foo_FLD_COUNT symbol with the number of * foo_FLD_name=value symbols that were set, * where value could be a comma-separated list. */ sprintf( symname, "%sFLD_COUNT", Fprefix ); symbol.dsc$w_length = strlen( symname ); sprintf(KeyCount, "%d", FLDCount); value.dsc$a_pointer = KeyCount; value.dsc$w_length = strlen ( KeyCount ); status = LIB$SET_SYMBOL ( &symbol, &value, &table ); if ( (status&1) == 0 ) fprintf(stderr, "Error defining %s symbol. status: %d\n", symname, status ); /* * Output the list of unique names as the foo_FIELDS symbol. */ sprintf( symname, "%sFIELDS", Fprefix ); symbol.dsc$w_length = strlen ( symname ); value.dsc$w_length = strlen( sym_list ); value.dsc$a_pointer = sym_list; status = LIB$SET_SYMBOL ( &symbol, &value, &table ); if ( (status&1) == 0 ) fprintf(stderr, "Error defining %s symbol. status: %d\n", symname, status ); /* * Output a foo_FIELDS_COUNT symbol with * the number of (comma-separated) names in the list * (might be less than foo_FLD_COUNT). */ sprintf( symname, "%sFIELDS_COUNT", Fprefix ); symbol.dsc$w_length = strlen( symname ); sprintf(KeyCount, "%d", FIELDSCount); value.dsc$a_pointer = KeyCount; value.dsc$w_length = strlen ( KeyCount ); status = LIB$SET_SYMBOL ( &symbol, &value, &table ); if ( (status&1) == 0 ) fprintf(stderr, "Error defining %s symbol. status: %d\n", symname, status ); return; }