Changeset 155 for trunk/gsdl/src/recpt/receptionist.cpp
- Timestamp:
- 1999-02-08T14:28:04+13:00 (25 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/gsdl/src/recpt/receptionist.cpp
r150 r155 12 12 /* 13 13 $Log$ 14 Revision 1.5 1999/02/08 01:28:02 rjmcnab 15 16 Got the receptionist producing something using the statusaction. 17 14 18 Revision 1.4 1999/02/05 10:42:46 rjmcnab 15 19 … … 31 35 #include "receptionist.h" 32 36 #include "fileutil.h" 37 #include "cgiutils.h" 33 38 #include <assert.h> 34 39 #include <time.h> … … 61 66 } 62 67 63 64 // sets the http address of the images directory. This is used to 65 // speed up the access to the images which are a part of the general 66 // interface. If this is not set the interface will have to get the 67 // images via gwcgi which will be a lot slower (especially if the 68 // browser does not cache the images). 69 void receptionist::set_httpimg (const text_t &thehttpimg) { 70 httpimg = thehttpimg; 71 } 72 73 // sets the http address of the gateway cgi program (ie. the program 74 // that contains this receptionist). 75 void receptionist::set_gwcgi (const text_t &thegwcgi) { 76 gwcgi = thegwcgi; 77 } 78 68 // configure_actions should be called for each line in the 69 // configuration files to configure the actions. The configuration 70 // should take place after all the actions have been added. 71 void receptionist::configure_actions (const text_t &key, const text_tarray &cfgline) { 72 actionptrmap::iterator here = actions.begin (); 73 actionptrmap::iterator end = actions.end (); 74 75 while (here != end) { 76 assert ((*here).second.a != NULL); 77 if ((*here).second.a != NULL) 78 (*here).second.a->configure(key, cfgline); 79 80 here++; 81 } 82 } 79 83 80 84 // init should be called after setgsdhome has been called. … … 84 88 // produced by the calling code. 85 89 bool receptionist::init (ostream &logout) { 86 // redirect the error output to logout 87 // disp.setlogout (&logout); 88 89 // set default values for the configuration file 90 // cfg_info.defaultaction = "p"; 91 // cfg_info.defaultpage = "about"; 92 // cfg_info.defaultencoding = "w"; 93 94 // load up the default macro files, the collection directory 95 // is searched first for the file and then the main directory 96 // text_t colmacrodir = filename_cat (collectdir, "macros"); 97 // text_t gsdlmacrodir = filename_cat (gsdlhome, "macros"); 98 // text_tarray::iterator arrhere = cfg_info.macrofiles.begin(); 99 // text_tarray::iterator arrend = cfg_info.macrofiles.end(); 100 // while (arrhere != arrend) { 101 // filename = filename_cat (colmacrodir, *arrhere); 102 // if (!file_exists (filename)) { 103 // filename = filename_cat (gsdlmacrodir, *arrhere); 104 // } 105 // disp.loaddefaultmacros(filename); 106 // arrhere++; 107 // } 108 109 srand(time(NULL)); 90 // read in the macro files 91 if (!read_macrofiles (logout)) return false; 92 93 // defined the main cgi arguments 94 if (!define_mainargs (logout)) return false; 95 96 // add the cgi arguments from the actions 97 actionptrmap::iterator here = actions.begin (); 98 actionptrmap::iterator end = actions.end (); 99 while (here != end) { 100 assert ((*here).second.a != NULL); 101 if ((*here).second.a != NULL) { 102 if (!argsinfo.addarginfo (&logout, (*here).second.a->getargsinfo())) 103 return false; 104 } 105 here++; 106 } 107 108 // create a saveconf string if there isn't one already 109 if (saveconf.empty()) 110 saveconf = create_save_conf_str (argsinfo, logout); 111 112 // check the saveconf string 113 if (!check_save_conf_str (saveconf, argsinfo, logout)) 114 return false; 115 116 // set a random seed 117 srand (time(NULL)); 110 118 111 119 // utf8outconvert.set_rzws(1); … … 116 124 117 125 118 // produce_cgi_page will call parse_cgi_args, get_cgihead_info and 126 // parse_cgi_args parses cgi arguments into an argument class. 127 // This function should be called for each page request. It returns false 128 // if there was a major problem with the cgi arguments. 129 bool receptionist::parse_cgi_args (const text_t &argstr, cgiargsclass &args, 130 ostream &logout) { 131 outconvertclass text_t2ascii; 132 133 // get an initial list of cgi arguments 134 args.clear(); 135 split_cgi_args (argstr, args); 136 137 // expand the compressed argument (if there was one) 138 if (!expand_save_args (argsinfo, saveconf, args, logout)) return false; 139 140 // add the defaults 141 add_default_args (argsinfo, args, logout); 142 143 // check the main cgi arguments 144 if (!check_mainargs (args, logout)) return false; 145 146 // check the arguments for the action 147 action *a = actions.getaction (args["a"]); 148 if (a != NULL) { 149 if (!a->check_cgiargs (args, logout)) return false; 150 } else { 151 // the action was not found!! 152 logout << text_t2ascii << "Error: the action \"" << args["a"] 153 << "\" could not be found.\n"; 154 return false; 155 } 156 157 return true; 158 } 159 160 161 // produce_cgi_page will call get_cgihead_info and 119 162 // produce_content in the appropriate way to output a cgi header and 120 // the page content (if needed). 121 void receptionist::produce_cgi_page (const text_t &argstr, ostream &contentout, 163 // the page content (if needed). If a page could not be created it 164 // will return false 165 bool receptionist::produce_cgi_page (cgiargsclass &args, ostream &contentout, 122 166 ostream &logout) { 123 contentout << "Content-type: text/plain\n\nHello\n"; 167 outconvertclass text_t2ascii; 168 169 response_t response; 170 text_t response_data; 171 172 // produce cgi header 173 get_cgihead_info (args, response, response_data, logout); 174 if (response == location) { 175 // I've forgotten how to do this :-/ 176 return true; 177 } else if (response == content) { 178 // content response 179 contentout << text_t2ascii << "Content-type: " << response_data << "\n\n"; 180 } else { 181 // unknown response 182 logout << "Error: get_cgihead_info returned an unknown response type.\n"; 183 return false; 184 } 185 186 // produce cgi page 187 if (!produce_content (args, contentout, logout)) return false; 188 189 // flush contentout 124 190 contentout << flush; 125 } 126 127 128 // parse_cgi_args parses cgi arguments into an argument class. 129 // This function should be called for each page request. 130 void receptionist::parse_cgi_args (const text_t &argstr, cgiargsclass &args, 131 ostream &logout) { 191 return true; 132 192 } 133 193 … … 140 200 void receptionist::get_cgihead_info (cgiargsclass &args, response_t &response, 141 201 text_t &response_data, ostream &logout) { 202 outconvertclass text_t2ascii; 203 204 // get the action 205 action *a = actions.getaction (args["a"]); 206 if (a != NULL) { 207 a->get_cgihead_info (args, response, response_data, logout); 208 209 } else { 210 // the action was not found!! 211 logout << text_t2ascii << "Error receptionist::get_cgihead_info: the action \"" 212 << args["a"] << "\" could not be found.\n"; 213 response = content; 214 response_data = "text/html"; 215 } 142 216 } 143 217 144 218 145 219 // produce the page content 146 voidreceptionist::produce_content (cgiargsclass &args, ostream &contentout,220 bool receptionist::produce_content (cgiargsclass &args, ostream &contentout, 147 221 ostream &logout) { 222 outconvertclass text_t2ascii; 223 224 // decide on the output conversion class 225 226 // produce the page using the desired action 227 action *a = actions.getaction (args["a"]); 228 if (a != NULL) { 229 if (!a->do_action (args, text_t2ascii, contentout, logout)) 230 return false; 231 232 } else { 233 // the action was not found!! 234 logout << text_t2ascii << "Error receptionist::produce_content: the action \"" 235 << args["a"] << "\" could not be found.\n"; 236 237 contentout << text_t2ascii << "<html>\n"; 238 contentout << text_t2ascii << "<head>\n"; 239 contentout << text_t2ascii << "<title>Error</title>\n"; 240 contentout << text_t2ascii << "</head>\n"; 241 contentout << text_t2ascii << "<body>\n"; 242 contentout << text_t2ascii << "<h2>Oops!</h2>\n"; 243 contentout << text_t2ascii << "Undefined Page. The action \"" 244 << args["a"] << "\" could not be found.\n"; 245 contentout << text_t2ascii << "</body>\n"; 246 contentout << text_t2ascii << "</html>\n"; 247 } 248 249 return true; 148 250 } 149 251 … … 154 256 return ""; 155 257 } 258 259 260 // will read in all the macro files. If one is not found an 261 // error message will be written to logout and the method will 262 // return false. 263 bool receptionist::read_macrofiles (ostream &logout) { 264 outconvertclass text_t2ascii; 265 266 // redirect the error output to logout 267 disp.setlogout (&logout); 268 269 // load up the default macro files, the collection directory 270 // is searched first for the file (if this is being used in 271 // collection specific mode) and then the main directory 272 text_t colmacrodir = filename_cat (collectdir, "macros"); 273 text_t gsdlmacrodir = filename_cat (gsdlhome, "macros"); 274 text_tarray::iterator arrhere = macrofiles.begin(); 275 text_tarray::iterator arrend = macrofiles.end(); 276 text_t filename; 277 while (arrhere != arrend) { 278 // filename is used as a flag to indicate whether 279 // the macro file has been found 280 filename.clear(); 281 282 // try in the collection directory if this is being 283 // run in collection specific mode 284 if (!collection.empty()) { 285 filename = filename_cat (colmacrodir, *arrhere); 286 if (!file_exists (filename)) filename.clear (); 287 } 288 289 // if we haven't found the macro file yet try in 290 // the main macro directory 291 if (filename.empty()) { 292 filename = filename_cat (gsdlmacrodir, *arrhere); 293 if (!file_exists (filename)) filename.clear (); 294 } 295 296 // see if we found the file or not 297 if (filename.empty()) { 298 logout << text_t2ascii 299 << "Error: the macro file \"" << *arrhere << "\" could not be found.\n"; 300 if (collection.empty()) { 301 logout << text_t2ascii 302 << "It should be in " << gsdlmacrodir << ".\n\n"; 303 } else { 304 logout << text_t2ascii 305 << "It should be in either " << colmacrodir << " or in " 306 << gsdlmacrodir << ".\n\n"; 307 } 308 return false; 309 310 } else { // found the file 311 disp.loaddefaultmacros(filename); 312 } 313 314 arrhere++; 315 } 316 317 // success 318 return true; 319 } 320 321 322 // Will define the main general arguments used by the receptionist. 323 // If an error occurs a message will be written to logout and the 324 // method will return false. 325 bool receptionist::define_mainargs (ostream &logout) { 326 // create a list of cgi arguments 327 cgiarginfo ainfo; 328 329 ainfo.shortname = "e"; 330 ainfo.longname = "compressed arguments"; 331 ainfo.multiplechar = true; 332 ainfo.defaultstatus = cgiarginfo::good; 333 ainfo.argdefault = ""; 334 ainfo.savedarginfo = cgiarginfo::mustnot; 335 if (!argsinfo.addarginfo (&logout, ainfo)) return false; 336 337 ainfo.shortname = "a"; 338 ainfo.longname = "action"; 339 ainfo.multiplechar = true; 340 ainfo.defaultstatus = cgiarginfo::none; 341 ainfo.argdefault = ""; 342 ainfo.savedarginfo = cgiarginfo::must; 343 if (!argsinfo.addarginfo (&logout, ainfo)) return false; 344 345 // w=western 346 ainfo.shortname = "w"; 347 ainfo.longname = "encoding"; 348 ainfo.multiplechar = true; 349 ainfo.defaultstatus = cgiarginfo::weak; 350 ainfo.argdefault = "w"; 351 ainfo.savedarginfo = cgiarginfo::must; 352 if (!argsinfo.addarginfo (&logout, ainfo)) return false; 353 354 ainfo.shortname = "nw"; 355 ainfo.longname = "new encoding"; 356 ainfo.multiplechar = true; 357 ainfo.defaultstatus = cgiarginfo::none; 358 ainfo.argdefault = ""; 359 ainfo.savedarginfo = cgiarginfo::mustnot; 360 if (!argsinfo.addarginfo (&logout, ainfo)) return false; 361 362 ainfo.shortname = "c"; 363 ainfo.longname = "collection"; 364 ainfo.multiplechar = true; 365 if (collection.empty()) { 366 ainfo.defaultstatus = cgiarginfo::none; 367 ainfo.argdefault = ""; 368 ainfo.savedarginfo = cgiarginfo::must; 369 } else { 370 ainfo.defaultstatus = cgiarginfo::good; 371 ainfo.argdefault = collection; 372 ainfo.savedarginfo = cgiarginfo::can; 373 } 374 if (!argsinfo.addarginfo (&logout, ainfo)) return false; 375 376 // 0=text+graphics, 1=text 377 ainfo.shortname = "v"; 378 ainfo.longname = "version"; 379 ainfo.multiplechar = false; 380 ainfo.defaultstatus = cgiarginfo::weak; 381 ainfo.argdefault = "0"; 382 ainfo.savedarginfo = cgiarginfo::can; 383 if (!argsinfo.addarginfo (&logout, ainfo)) return false; 384 385 // 0=normal, 1=big 386 ainfo.shortname = "f"; 387 ainfo.longname = "query box size"; 388 ainfo.multiplechar = false; 389 ainfo.defaultstatus = cgiarginfo::weak; 390 ainfo.argdefault = "0"; 391 ainfo.savedarginfo = cgiarginfo::can; 392 if (!argsinfo.addarginfo (&logout, ainfo)) return false; 393 394 // the interface language name should use the ISO 639 395 // standard 396 ainfo.shortname = "l"; 397 ainfo.longname = "interface language"; 398 ainfo.multiplechar = true; 399 ainfo.defaultstatus = cgiarginfo::weak; 400 ainfo.argdefault = "en"; 401 ainfo.savedarginfo = cgiarginfo::must; 402 if (!argsinfo.addarginfo (&logout, ainfo)) return false; 403 404 return true; 405 } 406 407 408 // check_mainargs will check all the main arguments. If a major 409 // error is found it will return false and no cgi page should 410 // be created using the arguments. 411 bool receptionist::check_mainargs (cgiargsclass &args, ostream &logout) { 412 // if this receptionist is running in collection dependant mode 413 // then it should always set the collection argument to the 414 // collection 415 if (!collection.empty()) args["c"] = collection; 416 417 // argument "v" can only be 0 or 1. Use the default value 418 // if it is out of range 419 int arg_v = args.getintarg ("v"); 420 if (arg_v != 0 && arg_v != 1) { 421 cgiarginfo *vinfo = argsinfo.getarginfo ("v"); 422 if (vinfo != NULL) args["v"] = vinfo->argdefault; 423 } 424 425 // argument "f" can only be 0 or 1. Use the default value 426 // if it is out of range 427 int arg_f = args.getintarg ("f"); 428 if (arg_f != 0 && arg_f != 1) { 429 cgiarginfo *finfo = argsinfo.getarginfo ("f"); 430 if (finfo != NULL) args["f"] = finfo->argdefault; 431 } 432 433 return true; 434 }
Note:
See TracChangeset
for help on using the changeset viewer.