root/main/trunk/greenstone2/runtime-src/src/recpt/wizardaction.cpp @ 23012

Revision 23012, 23.9 KB (checked in by ak19, 9 years ago)

Fix to bug causing depositor to crash library.cgi upon selecting a collection: code was previously looping on parameter names in args to substring them in order to compare them to a prefix. However, it also tried to substring them when the arg parameter name was shorter than the prefix. Fix was necessary in two locations (wizardaction and depositoraction).

  • Property svn:keywords set to Author Date Id Revision
Line 
1/**********************************************************************
2 *
3 * wizardaction.cpp --
4 * Copyright (C) 2000  The New Zealand Digital Library Project
5 *
6 * A component of the Greenstone digital library software
7 * from the New Zealand Digital Library Project at the
8 * University of Waikato, New Zealand.
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23 *
24 *********************************************************************/
25
26#include "gsdl_modules_cfg.h"
27#ifdef GSDL_USE_WIZARD_ACTION
28
29// note that the wizardaction relies on having direct access to a
30// collections configuration file. this breaks the separation between
31// receptionist and collection server and so is not suitable (at least
32// in its current form) for use when collection servers are separate
33// from the receptionist (e.g. when using the CORBA protocol).
34
35// following line required to get fstream.filedesc() on darwin (Mac OS X)
36#define _STREAM_COMPAT  1
37// required for utsname on solaris???
38#ifndef _XOPEN_SOURCE
39#define _XOPEN_SOURCE 1
40#endif
41// This was added for Solaris, but it makes things worse on Solaris for me...
42// #define _XOPEN_SOURCE_EXTENDED 1
43
44#include "wizardaction.h"
45#include "OIDtools.h"
46#include "fileutil.h"
47#include "cfgread.h"
48#include "gsdltools.h"
49#include "gsdltimes.h"
50#include "argdb.h"
51#include "cgiutils.h"
52#include <stdio.h>
53#include <fcntl.h>
54
55#if !defined (__WIN32__)
56#include <sys/utsname.h>
57#include <unistd.h>
58#endif
59
60wizardaction::wizardaction () {
61
62  recpt = NULL;
63  disabled = true;
64
65  macro_prefix = "";
66}
67
68wizardaction::~wizardaction () {
69}
70
71void wizardaction::configure (const text_t &key, const text_tarray &cfgline) {
72 
73  const text_t& action_name = get_action_name();
74
75  if ((key == action_name) && (cfgline.size() == 1) &&
76      (cfgline[0] == "true" || cfgline[0] == "on" || cfgline[0] == "enabled")) {
77    disabled = false;
78  } else {
79    // call the parent class to deal with the things which
80    // are not dealt with here
81    action::configure (key, cfgline);
82  }
83}
84
85
86bool wizardaction::init (ostream & /*logout*/) {
87
88  return set_gsdl_env_vars(gsdlhome);
89}
90
91
92void wizardaction::get_cgihead_info (cgiargsclass &/*args*/, recptprotolistclass * /*protos*/,
93                    response_t &response,text_t &response_data,
94                    ostream &/*logout*/) {
95  response = content;
96  response_data = "text/html";
97}
98
99
100bool wizardaction::check_cgiargs (cgiargsinfoclass &argsinfo, cgiargsclass &args,
101                     recptprotolistclass * /*protos*/, ostream &logout) {
102 
103  text_t current_page = args["p"];
104
105  if (current_page != "intro" &&
106      current_page != "bildframe1" && current_page != "new" && current_page != "select") {
107    // update arguments that were saved to the harddrive
108    text_tmap saved_args;
109   
110    // update the argdb database with any arguments that were set
111    // by previous page as denoted by prefix (eg. di1 or bc1)
112
113    cgiargsclass::const_iterator args_here = args.begin();
114    cgiargsclass::const_iterator args_end = args.end();
115
116    while (args_here != args_end) {
117      text_t args_name = (*args_here).first;
118     
119      int prefix_len = macro_prefix.size();
120      int args_name_len = args_name.size();
121
122      if(args_name_len >= prefix_len) { // Only now can we substring args_name by prefix_len
123          text_t args_prefix;
124          if(args_name_len > prefix_len) { // substring
125            args_prefix = substr(args_name.begin(),args_name.begin()+prefix_len);
126          } else {
127            args_prefix = args_name;
128          }
129     
130          if (args_prefix == macro_prefix) {
131            saved_args[args_name] = args[args_name];
132          }
133      }
134      ++args_here;
135    }
136     
137    argdb *args_on_disk = new argdb(gsdlhome,args[macro_prefix+"tmp"]);
138    if (!args_on_disk->update_args(saved_args)) {
139      // error
140      logout << "wizardaction: argdb::update_args failed\n";
141    }
142   
143    // update args from argdb
144    saved_args.erase(saved_args.begin(), saved_args.end());
145    if (!args_on_disk->get_args(saved_args)) {
146      // error
147      logout << "wizardaction: argdb::get_args failed\n";
148    }
149    delete args_on_disk;
150   
151    text_tmap::iterator sa_here = saved_args.begin();
152    text_tmap::iterator sa_end = saved_args.end();
153    while (sa_here != sa_end) {
154      if (!(*sa_here).second.empty()) {
155    args[(*sa_here).first] = (*sa_here).second;
156      }
157      ++sa_here;
158    }  bool first = true;
159
160  }
161
162  return true;
163}
164
165// tests if collection is write protected (currently just checks if
166// collect.cfg file is writable
167bool wizardaction::collection_protected (const text_t &collection) {
168  text_t cfgfile = filename_cat(collecthome, collection, "etc", "collect.cfg");
169  if (file_writable(cfgfile)) return false;
170  return true;
171}
172
173// set the _statusline_ macro
174void wizardaction::set_statusline (displayclass &disp, cgiargsclass &args, ostream & /*logout*/) {
175
176  // the build command creates .bld.download, .bld.import, and .bld.build files (in that
177  // order) and deletes them (also in that order) when each stage is complete. the .bld
178  // file is the concatenation of all these files.
179  text_t bld_file = filename_cat (gsdlhome, "tmp", args[macro_prefix+"tmp"], args[macro_prefix+"dirname"] + ".bld");
180  text_t statusline;
181
182  if (file_exists (bld_file + ".download")) {
183    statusline = "_collector:textdownloadingfiles_<br>\n";
184    statusline += dm_safe(file_tail(bld_file + ".download", 1, 0));
185  } else if (file_exists (bld_file + ".import")) {
186    statusline = "_collector:textimportingcollection_<br>\n";
187    statusline += dm_safe(file_tail(bld_file + ".import", 1, 0));
188  } else if (file_exists (bld_file + ".build")) {
189    statusline = "_collector:textbuildingcollection_<br>\n";
190    statusline += dm_safe(file_tail(bld_file + ".build", 1, 0));
191  } else {
192    statusline += "_collector:textcreatingcollection_<br>\n";
193    statusline += dm_safe(file_tail(bld_file, 1, 0));
194  }
195
196  disp.setmacro ("statusline", "collector", statusline);
197  disp.setmacro ("statusline", "depositor", statusline);
198}
199
200
201// if sw = 0 replace all carriage returns in intext with the string "\n"
202// else replace all occurances of "\n" with a carriage return
203text_t wizardaction::carriage_replace (const text_t &intext, int sw) {
204   
205  text_t outtext;
206  text_t::const_iterator here = intext.begin();
207  text_t::const_iterator end = intext.end();
208  while (here != end) {
209    if (sw == 0) {
210      if (*here == '\n') {
211    if ((here+1) != end && *(here+1) == '\r') ++here;
212    outtext += "\\n";
213      } else if (*here == '\r') {
214    if ((here+1) != end && *(here+1) == '\n') ++here;
215    outtext += "\\n";
216      } else {
217    outtext.push_back (*here);
218      }
219    } else if (*here == '\\' && (here+1) != end && *(here+1) == 'n') {
220      outtext.push_back ('\n');
221      ++here;
222    } else {
223      outtext.push_back (*here);
224    }
225    ++here;
226  }
227  return outtext;
228}
229
230
231// create a short directory name from fullname
232text_t wizardaction::get_directory_name (const text_t &fullname) {
233
234  text_t shortname;
235  if (fullname.empty()) {
236    shortname = "coll";
237
238  } else {
239   
240    // first make all lowercase and remove any dodgy characters
241    // (i.e. anything not [a-z]
242    text_t::const_iterator here = fullname.begin();
243    text_t::const_iterator end = fullname.end();
244    while (here != end) {
245      if ((*here >= 'A' && *here <= 'Z') || (*here >= 'a' && *here <= 'z') ||
246      (*here == ' ')) {
247    if (*here >= 'A' && *here <= 'Z') shortname.push_back (*here+32);
248    else if (*here == ' ') {
249      while ((*(here+1)) == ' ') ++here;
250      shortname.push_back (*here);
251    } else shortname.push_back (*here);
252      }
253      ++here;
254    }
255
256    text_tarray words;
257    splitchar (shortname.begin(), shortname.end(), ' ', words);
258    int num_words = words.size();
259
260    if (num_words == 0) {
261      shortname = "coll";
262
263    } else {
264
265      shortname.clear();
266      int use_words = (num_words <= 6) ? num_words : 6;
267      unsigned int substr_len = 6 / use_words;
268     
269      for (int i = 0; i < use_words; ++i) {
270    if (words[i].size() < substr_len) shortname += words[i];
271    else shortname += substr (words[i].begin(), words[i].begin()+substr_len);
272      }
273    }
274  }
275
276  // check to see if shortname is unique
277  text_t fulldirname = filename_cat (collecthome, shortname);
278  if (directory_exists (fulldirname)) {
279    int version = 0;
280    text_t newname;
281    do {
282      ++version;
283      newname = shortname;
284      newname.push_back ('v');
285      newname.appendint (version);
286      fulldirname = filename_cat (collecthome, newname);
287    } while (directory_exists (fulldirname));
288
289    shortname = newname;
290  }
291 
292  return shortname;
293}
294
295// assigns a temporary directory name for this collector session
296// and creates temporary directory
297// returns false if it couldn't create the directory
298bool wizardaction::assign_tmpname (cgiargsclass &args, ostream &logout) {
299
300  int i = 0;
301  text_t tmpname = "tbuild";
302  while (directory_exists (filename_cat (gsdlhome, "tmp", tmpname + text_t(i)))) {
303    ++i;
304  }
305  tmpname.appendint (i);
306
307  text_t fulltmpdir = filename_cat (gsdlhome, "tmp", tmpname);
308  if (!mk_dir (fulltmpdir)) {
309    outconvertclass text_t2ascii;
310    logout << text_t2ascii << "wizardaction::assign_tmpname unable to create directory ("
311       << fulltmpdir << ")\n";
312    return false;
313  }
314
315  args[macro_prefix + "tmp"] = tmpname;
316  return true;
317}
318
319// set the _fullnamemenu_ macro (and _warnindex_ and _selectedindex_ if
320// we're on the "srce" page)
321void wizardaction::set_fullnamemenu (displayclass &disp, cgiargsclass &args,
322                    recptprotolistclass *protos, ostream &logout) {
323
324  if (recpt == NULL) {
325    logout << "ERROR (wizardaction::set_fullnamemenu): This action does not contain\n"
326       << "       information about any receptionists. The method set_receptionist was\n"
327       << "       probably not called from the module which instantiated this action.\n";
328    return;
329  }
330
331  text_t &current_page = args["p"];
332  text_t currentname = args[macro_prefix+"dirname"];
333  if (current_page == "srce") currentname = args[macro_prefix + "clonecol"];
334
335  text_tarray dirnames;
336  text_tarray fullnames;
337  vector<bool> write_protected;
338  text_tarray  build_type;
339
340  bool is_selected = false;
341  int selected_index = 0;
342  int index = 0;
343
344  recptprotolistclass::iterator rprotolist_here = protos->begin();
345  recptprotolistclass::iterator rprotolist_end = protos->end();
346  while (rprotolist_here != rprotolist_end) {
347    if ((*rprotolist_here).p != NULL) {
348
349      // don't include z39.50 collections
350      comerror_t err = noError;
351      if ((*rprotolist_here).p->get_protocol_name (err) == "z3950proto") {
352    ++rprotolist_here;
353    continue;
354      }
355
356      text_tarray collist;
357      (*rprotolist_here).p->get_collection_list (collist, err, logout);
358      if (err == noError) {
359    text_tarray::iterator collist_here = collist.begin();
360    text_tarray::iterator collist_end = collist.end();
361    while (collist_here != collist_end) {
362      ColInfoResponse_t *cinfo = recpt->get_collectinfo_ptr ((*rprotolist_here).p, *collist_here, logout);
363      if (cinfo != NULL) {
364        text_t collectionname = cinfo->get_collectionmeta("collectionname", args["l"]);
365        if (collectionname.empty()) {
366          collectionname = *collist_here;
367        }
368        dirnames.push_back(*collist_here);
369        fullnames.push_back(collectionname);
370        // check to see if the collection is writable
371        if (collection_protected (*collist_here)) write_protected.push_back(true);
372        else write_protected.push_back(false);
373
374        // remember build type for collection (mg, mgpp, lucene, ...)
375        // used to determine cgi arg 'ct' later on and minus option to 'build'
376        build_type.push_back(cinfo->buildType);
377
378        if (*collist_here == currentname) {
379          is_selected = true;
380          selected_index = index;       
381        }
382        ++index;
383      }
384      ++collist_here;
385    }
386      }
387    }
388    ++rprotolist_here;
389  }
390
391  bool first = true;
392
393  text_t warnindex;
394  text_t fullnamemenu = "<select name=\""+macro_prefix+"dirname\" onChange=\"menuchange();\">\n";
395  text_t buildtype_jsarray = "var buildtype = new Array(";
396
397  fullnamemenu += "<option value=\"\">_textselectoption_</option>\n";
398  buildtype_jsarray += "\"\" ";
399
400  for (int i = 0; i < index; ++i) {
401    // don't want write protected collections in list on "change existing
402    // collection" page
403    if (write_protected[i] && current_page == "existing") continue;
404    fullnamemenu += "<option value=\"" + dirnames[i] + "\"";
405    if (is_selected && i == selected_index) {
406      fullnamemenu += " selected";
407      ++selected_index;
408      is_selected = false;
409    }
410    fullnamemenu.push_back ('>');
411    fullnamemenu += fullnames[i] + " ("+dirnames[i]+")";
412    fullnamemenu.push_back ('\n');
413
414    buildtype_jsarray += ", \"" + build_type[i] + "\"";
415   
416    first = false;
417  }
418  fullnamemenu += "</select>\n";
419
420  buildtype_jsarray += ");";
421
422  text_t action_name = get_action_name();
423  disp.setmacro ("fullnamemenu", action_name, fullnamemenu);
424  disp.setmacro ("buildtypearray", action_name, buildtype_jsarray);
425}
426
427// checks to see if any of the plugins in pluginset occur in
428// collections configuration file
429bool wizardaction::uses_weird_plugin (const text_t &collection) {
430
431  text_tset pluginset;
432  pluginset.insert ("HBPlug");
433
434  text_t cfgfile_content;
435  text_t cfgfile_name = filename_cat (collecthome, collection, "etc", "collect.cfg");
436  text_t pluginstr, pluginname;
437
438  if (read_file (cfgfile_name, cfgfile_content)) {
439    text_t::const_iterator here = cfgfile_content.begin();
440    text_t::const_iterator end = cfgfile_content.end();
441    while (here != end) {
442      here = findchar (here, end, 'p');
443      if (here == end) break;
444      if ((here+6 < end) && (substr (here, here+6) == "plugin")) {
445    getdelimitstr (here+6, end, '\n', pluginstr);
446    text_t::const_iterator hp = pluginstr.begin();
447    text_t::const_iterator ep = pluginstr.end();
448    bool found = false;
449    // remove any leading whitespace, trailing options etc.
450    while (hp != ep) {
451      if (*hp == '\t' || *hp == ' ' || *hp == '\n') {
452        if (found) break;
453      } else {
454        pluginname.push_back (*hp);
455        found = true;
456      }
457      ++hp;
458    }
459    text_tset::const_iterator it = pluginset.find (pluginname);
460    if (it != pluginset.end()) return true; // found matching plugin
461    pluginname.clear();
462      }
463      ++here;
464    }
465  }
466  return false;
467}
468
469void wizardaction::gsdl_build (cgiargsclass &args, ostream &logout) {
470
471  outconvertclass text_t2ascii;
472
473  //check to see if the tbuild directory exists
474  text_t tmpdir = filename_cat (gsdlhome, "tmp", args[macro_prefix+"tmp"]);
475  if (!directory_exists (tmpdir)) {
476    message = "tmpfail";
477    return;
478  }
479 
480  //check to see if collection name specified
481  text_t &collection = args[macro_prefix+"dirname"];
482  if (collection.empty()) {
483    message = "nocollection";
484    return;
485  }
486
487  // check for a .build file - if it exists then we've already built
488  // the collection (or are in the process of building it)
489  text_t buildfile = filename_cat (tmpdir, ".build");
490  if (file_exists (buildfile)) {
491    return;
492  } else {
493    // create the .build file (this file is just a place holder to let any future
494    // pages know that we've already been here)
495    char *buildfilec = buildfile.getcstr();
496    ofstream bfile_out (buildfilec);
497    delete []buildfilec;
498    if (bfile_out) {
499      bfile_out << "collection building\n";
500      bfile_out.close();
501    } else {
502      message = "tmpfail";
503      return;
504    }
505  }
506
507  //FLAG!
508  const recptconf &rcinfo = recpt->get_configinfo ();
509
510  // create the event header file if LogEvents, EmailEvents or
511  // EmailUserEvents options are turned on.
512  bool logevents =
513    (rcinfo.LogEvents == CollectorEvents || rcinfo.LogEvents == AllEvents ||
514     rcinfo.EmailEvents == CollectorEvents || rcinfo.EmailEvents == AllEvents ||
515     rcinfo.EmailUserEvents);
516  text_t ehead_file = filename_cat (tmpdir, "ehead.txt");
517  if (logevents) {
518    if (!create_event_header_file (ehead_file, args, logout)) {
519      logevents = false;
520    }
521  }
522   
523  text_t collectdir = get_collectdir (args);
524
525  // set up build options
526  //text_t options = "-make_writable -remove_import -out \"";
527  text_t options = "-make_writable  -out \"";
528  options += filename_cat (tmpdir, collection + ".bld");
529  options += "\" -collectdir \"" + collectdir + "\" -statsfile \"";
530  options += filename_cat(collectdir, collection, "etc", "import.log") + "\"";
531
532  if (args[macro_prefix+"esrce"] == 1) {
533    // we're adding data to an existing collection
534    options += " -save_archives -append -manifest";
535  }
536
537  text_tarray inputvalues, inputtypes;
538  splitchar (args[macro_prefix+"input"].begin(), args[macro_prefix+"input"].end(), ',', inputvalues);
539  splitchar (args[macro_prefix+"inputtype"].begin(), args[macro_prefix+"inputtype"].end(), ',', inputtypes);
540  int numvalues = inputvalues.size();
541  int numtypes = inputtypes.size();
542  for (int i = 0; i < numvalues; ++i) {
543    if (!inputvalues[i].empty()) {
544      text_t type = "file://"; // default
545      if (i < numtypes) type = inputtypes[i];
546      options += " -download \"" +
547    remove_trailing_slashes(type + format_url(decode_commas(inputvalues[i]))) + "\"";
548    }
549  }
550
551  if (logevents) {
552    if (rcinfo.LogEvents == CollectorEvents || rcinfo.LogEvents == AllEvents)
553      options += " -log_events";
554    if (rcinfo.EmailEvents == CollectorEvents || rcinfo.EmailEvents == AllEvents) {
555      options += " -mail_server " + rcinfo.MailServer;
556      options += " -email_events " + rcinfo.maintainer;
557      if (rcinfo.EmailUserEvents) options += "," + args[macro_prefix+"contactemail"];
558    } else if (rcinfo.EmailUserEvents) {
559      options += " -mail_server " + rcinfo.MailServer;
560      options += " -email_events " + args[macro_prefix+"contactemail"];
561    }
562    options += " -event_header " + ehead_file;
563  }
564
565  text_t indextype = args[macro_prefix+"buildtype"];
566  if(indextype == "") {
567#ifdef ENABLE_MG
568    indextype = "mg";
569#else
570    cerr << "Unable to choose mg as the default indextype, since the Greenstone installation was not compiled with MG enabled." << endl;
571#endif
572  }
573  options += " -indextype \"" + indextype + "\"";
574
575  text_t optionfile = filename_cat (tmpdir, "build.opt");
576  char *optionfilec = optionfile.getcstr();
577  ofstream ofile_out (optionfilec);
578  delete []optionfilec;
579  if (!ofile_out) {
580    message = "tmpfail";
581    return;
582  }
583  ofile_out << text_t2ascii << options << "\n";
584  ofile_out.close();
585
586  // if we're altering an existing collection we need to kill off
587  // the existing collection server - we do this for the local library
588  // (and any other persistent version of the library) as the existing
589  // database file can't be deleted while the collection server holds it open
590  if ((args[macro_prefix+"econf"] == 1) || (args[macro_prefix+"esrce"] == 1)) {
591    remove_colservr (collection, logout);
592  }   
593
594  // set up the build command - build.bat has some issues with quoting
595  // on win2k when gsdlhome contains spaces so we'll avoid using
596  // "perl -S" here in favor of calling the "build" perl script explicitly
597  text_t build_cmd = "perl \"" + filename_cat (gsdlhome, "bin", "script", "build");
598  build_cmd += "\" -optionfile \"" + optionfile + "\" " + collection;
599
600  // run build command in background (i.e. asynchronously)
601  gsdl_system (build_cmd, false, logout);
602
603}
604
605void wizardaction::gsdl_cancel_build (cgiargsclass &args, ostream &logout) {
606  // I really wanted to do what this perl script does from within the library
607  // c++ code. I ran into some problems though (like how do you write a portable
608  // "rm -r" in c++?). One day I'll spend some time sorting it out ... maybe.
609  text_t cancel_cmd = "perl -S cancel_build.pl -collectdir \"";
610  cancel_cmd += filename_cat (gsdlhome, "tmp", args[macro_prefix+"tmp"]) + "\" ";
611  cancel_cmd += args[macro_prefix+"dirname"];
612  // To be on the safe side we'll make this a synchronous call
613  // so that all tidying up is done before the user has a chance
614  // to do anything else (like start rebuilding their collection).
615  // This means that for a big collection where there's lots of
616  // stuff to delete etc. it might take a while before the "build
617  // cancelled" page appears.
618  gsdl_system (cancel_cmd, true, logout);
619}
620
621text_t wizardaction::get_collectdir (cgiargsclass &args)
622{
623  if ((args[macro_prefix+"econf"] == 1) || (args[macro_prefix+"esrce"] == 1)) {
624    // we're adding to a collection in place
625    return collecthome;
626  }
627  else {
628    return filename_cat (gsdlhome, "tmp", args[macro_prefix+"tmp"]);
629  }
630}
631
632// create and initialize a new collection server and
633// add it to the null protocol.
634void wizardaction::create_colserver (const text_t &collection, ostream &logout) {
635
636  recptprotolistclass *protos = recpt->get_recptprotolist_ptr();
637  recptprotolistclass::iterator rprotolist_here = protos->begin();
638  recptprotolistclass::iterator rprotolist_end = protos->end();
639  while (rprotolist_here != rprotolist_end) {
640    comerror_t err = noError;
641    if ((*rprotolist_here).p != NULL) {
642      if ((*rprotolist_here).p->get_protocol_name (err) == "nullproto") {
643    // create collection server and add it to nullproto
644    (*rprotolist_here).p->add_collection (collection, recpt, gsdlhome, collecthome, dbhome);
645    // make sure gsdlhome is configured
646    text_tarray tmp;
647    tmp.push_back (gsdlhome);
648    (*rprotolist_here).p->configure ("gsdlhome", tmp, err);
649    // re-initialize the null protocol
650    if (!(*rprotolist_here).p->init (err, logout)) {
651      logout << "wizardaction::create_colserver: nullproto init failed\n";
652    }
653    return;
654      }
655    }
656    ++rprotolist_here;
657  }
658
659  logout << "wizardaction::create_colserver: no valid nullproto found\n";
660}
661
662// delete a collection server from the null protocol
663void wizardaction::remove_colservr (const text_t &collection, ostream &logout) {
664
665  recpt->uncache_collection (collection);
666
667  recptprotolistclass *protos = recpt->get_recptprotolist_ptr();
668  recptprotolistclass::iterator rprotolist_here = protos->begin();
669  recptprotolistclass::iterator rprotolist_end = protos->end();
670  while (rprotolist_here != rprotolist_end) {
671    comerror_t err = noError;
672    if ((*rprotolist_here).p != NULL) {
673      if ((*rprotolist_here).p->get_protocol_name (err) == "nullproto") {
674    (*rprotolist_here).p->remove_collection (collection, logout);
675    return;
676      }
677    }
678    ++rprotolist_here;
679  }
680
681  logout << "wizardaction::create_colserver: no valid nullproto found\n";
682}
683
684bool wizardaction::create_event_header_file (const text_t &filename, cgiargsclass &args,
685                        ostream &logout) {
686
687  outconvertclass text_t2ascii;
688  char *filenamec = filename.getcstr();
689  ofstream eheadfile (filenamec);
690  delete []filenamec;
691
692  if (eheadfile) {
693    eheadfile << text_t2ascii << get_event_header (args);
694    eheadfile.close();
695    return true;
696  }
697   
698  logout << text_t2ascii << "wizardaction::create_event_header ERROR: Couldn't create "
699     << "Event Header file " << filename << ". Event logging disabled\n";
700  return false;
701}
702
703text_t wizardaction::get_event_header (cgiargsclass &args) {
704  text_t header = "Greenstone Username: " + args["un"] + "\n";
705  header += "Collection: " + args[macro_prefix+"dirname"] + "\n";
706  header += "Collection Creator: " + args[macro_prefix+"contactemail"] + "\n";
707  header += "GSDLHOME: " + gsdlhome + "\n";
708  header += "Build Location: " + get_collectdir(args) + "\n";
709
710  return header;
711}
712
713
714// format_url simply strips "http://", "ftp://", or "file://" off the
715// beginning of url if they're there
716text_t wizardaction::format_url (const text_t &url) {
717  text_t::const_iterator begin = url.begin();
718  text_t::const_iterator end = url.end();
719
720  if (url.size() >= 7) {
721    text_t prefix = substr(begin, begin+7);
722    if (prefix == "http://" || prefix == "file://") {
723      return substr(begin+7, end);
724    }
725  }
726  if (url.size() >= 6) {
727    if (substr(begin, begin+6) == "ftp://") {
728      return substr(begin+6, end);
729    }
730  }
731  return url;
732}
733
734text_t wizardaction::remove_trailing_slashes (text_t str) {
735
736  while (*(str.end()-1) == '\\') {
737    str.pop_back();
738  }
739  return str;
740}
741
742#endif //GSDL_USE_WIZARD_ACTION
Note: See TracBrowser for help on using the browser.