00001
00002
00003
00004
00005
00006
00007
00008
00009
00010 #include "config.h"
00011 #include "webcit.h"
00012 #include "webserver.h"
00013
00014
00015 #define UI_TEXT 0
00016 #define UI_DIALOG 2
00017 #define UI_SILENT 3
00018
00019 int setup_type;
00020 char setup_directory[SIZ];
00021 int using_web_installer = 0;
00022 char suggested_url[SIZ];
00023
00024
00025
00026
00027 void delete_init_entry(char *which_entry)
00028 {
00029 char *inittab = NULL;
00030 FILE *fp;
00031 char buf[SIZ];
00032 char entry[SIZ];
00033 char levels[SIZ];
00034 char state[SIZ];
00035 char prog[SIZ];
00036
00037 inittab = strdup("");
00038 if (inittab == NULL) return;
00039
00040 fp = fopen("/etc/inittab", "r");
00041 if (fp == NULL) return;
00042
00043 while(fgets(buf, sizeof buf, fp) != NULL) {
00044
00045 if (num_tokens(buf, ':') == 4) {
00046 extract_token(entry, buf, 0, ':', sizeof entry);
00047 extract_token(levels, buf, 1, ':', sizeof levels);
00048 extract_token(state, buf, 2, ':', sizeof state);
00049 extract_token(prog, buf, 3, ':', sizeof prog);
00050
00051 if (!strcmp(entry, which_entry)) {
00052 strcpy(state, "off");
00053 }
00054 }
00055
00056 inittab = realloc(inittab, strlen(inittab) + strlen(buf) + 2);
00057 if (inittab == NULL) {
00058 fclose(fp);
00059 return;
00060 }
00061
00062 strcat(inittab, buf);
00063 }
00064 fclose(fp);
00065 fp = fopen("/etc/inittab", "w");
00066 if (fp != NULL) {
00067 fwrite(inittab, strlen(inittab), 1, fp);
00068 fclose(fp);
00069 kill(1, SIGHUP);
00070 }
00071 free(inittab);
00072 }
00073
00074
00075
00076
00077
00078
00079
00080
00081 void delete_the_old_way(void) {
00082 FILE *infp;
00083 char buf[1024];
00084 char looking_for[1024];
00085 int have_entry = 0;
00086 char entry[1024];
00087 char prog[1024];
00088 char init_entry[1024];
00089
00090
00091 strcpy(init_entry, "");
00092
00093
00094 snprintf(looking_for, sizeof looking_for, "%s/webserver ", setup_directory);
00095
00096
00097
00098
00099 infp = fopen("/etc/inittab", "r");
00100 if (infp == NULL) {
00101 return;
00102 } else {
00103 while (fgets(buf, sizeof buf, infp) != NULL) {
00104 buf[strlen(buf) - 1] = 0;
00105 extract_token(entry, buf, 0, ':', sizeof entry);
00106 extract_token(prog, buf, 3, ':', sizeof prog);
00107 if (!strncasecmp(prog, looking_for,
00108 strlen(looking_for))) {
00109 ++have_entry;
00110 strcpy(init_entry, entry);
00111 }
00112 }
00113 fclose(infp);
00114 }
00115
00116
00117 if (!have_entry) return;
00118
00119 delete_init_entry(init_entry);
00120 }
00121
00122
00123
00124 void cleanup(int exitcode)
00125 {
00126 exit(exitcode);
00127 }
00128
00129
00130
00131 void title(char *text)
00132 {
00133 if (setup_type == UI_TEXT) {
00134 printf("\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n<%s>\n", text);
00135 }
00136 }
00137
00138
00139
00140
00141 int yesno(char *question, int default_value)
00142 {
00143 int i = 0;
00144 int answer = 0;
00145 char buf[SIZ];
00146
00147 switch (setup_type) {
00148
00149 case UI_TEXT:
00150 do {
00151 printf("%s\nYes/No [%s] --> ",
00152 question,
00153 ( default_value ? "Yes" : "No" )
00154 );
00155 fgets(buf, sizeof buf, stdin);
00156 answer = tolower(buf[0]);
00157 if ((buf[0]==0) || (buf[0]==13) || (buf[0]==10))
00158 answer = default_value;
00159 else if (answer == 'y')
00160 answer = 1;
00161 else if (answer == 'n')
00162 answer = 0;
00163 } while ((answer < 0) || (answer > 1));
00164 break;
00165
00166 case UI_DIALOG:
00167 sprintf(buf, "exec %s %s --yesno '%s' 15 75",
00168 getenv("CTDL_DIALOG"),
00169 ( default_value ? "" : "--defaultno" ),
00170 question);
00171 i = system(buf);
00172 if (i == 0) {
00173 answer = 1;
00174 }
00175 else {
00176 answer = 0;
00177 }
00178 break;
00179
00180 }
00181 return (answer);
00182 }
00183
00184
00185
00186
00187 void set_value(char *prompt, char str[])
00188 {
00189 char buf[SIZ];
00190 char dialog_result[PATH_MAX];
00191 char setupmsg[SIZ];
00192 FILE *fp;
00193
00194 strcpy(setupmsg, "");
00195
00196 switch (setup_type) {
00197 case UI_TEXT:
00198 title("WebCit setup");
00199 printf("\n%s\n", prompt);
00200 printf("This is currently set to:\n%s\n", str);
00201 printf("Enter new value or press return to leave unchanged:\n");
00202 fgets(buf, sizeof buf, stdin);
00203 buf[strlen(buf) - 1] = 0;
00204 if (strlen(buf) != 0)
00205 strcpy(str, buf);
00206 break;
00207
00208 case UI_DIALOG:
00209 CtdlMakeTempFileName(dialog_result, sizeof dialog_result);
00210 sprintf(buf, "exec %s --inputbox '%s' 19 72 '%s' 2>%s",
00211 getenv("CTDL_DIALOG"),
00212 prompt,
00213 str,
00214 dialog_result);
00215 system(buf);
00216 fp = fopen(dialog_result, "r");
00217 if (fp != NULL) {
00218 fgets(str, sizeof buf, fp);
00219 if (str[strlen(str)-1] == 10) {
00220 str[strlen(str)-1] = 0;
00221 }
00222 fclose(fp);
00223 unlink(dialog_result);
00224 }
00225 break;
00226
00227 }
00228 }
00229
00230
00231 void important_message(char *title, char *msgtext)
00232 {
00233 char buf[SIZ];
00234
00235 switch (setup_type) {
00236
00237 case UI_TEXT:
00238 printf("\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n");
00239 printf(" %s \n\n%s\n\n", title, msgtext);
00240 printf("Press return to continue...");
00241 fgets(buf, sizeof buf, stdin);
00242 break;
00243
00244 case UI_DIALOG:
00245 sprintf(buf, "exec %s --msgbox '%s' 19 72",
00246 getenv("CTDL_DIALOG"),
00247 msgtext);
00248 system(buf);
00249 break;
00250 }
00251 }
00252
00253
00254 void display_error(char *error_message)
00255 {
00256 important_message("Error", error_message);
00257 }
00258
00259 void progress(char *text, long int curr, long int cmax)
00260 {
00261 static long dots_printed = 0L;
00262 long a = 0;
00263 char buf[SIZ];
00264 static FILE *fp = NULL;
00265
00266 switch (setup_type) {
00267
00268 case UI_TEXT:
00269 if (curr == 0) {
00270 printf("%s\n", text);
00271 printf("..........................");
00272 printf("..........................");
00273 printf("..........................\r");
00274 fflush(stdout);
00275 dots_printed = 0;
00276 } else if (curr == cmax) {
00277 printf("\r%79s\n", "");
00278 } else {
00279 a = (curr * 100) / cmax;
00280 a = a * 78;
00281 a = a / 100;
00282 while (dots_printed < a) {
00283 printf("*");
00284 ++dots_printed;
00285 fflush(stdout);
00286 }
00287 }
00288 break;
00289
00290 case UI_DIALOG:
00291 if (curr == 0) {
00292 sprintf(buf, "exec %s --gauge '%s' 7 72 0",
00293 getenv("CTDL_DIALOG"),
00294 text);
00295 fp = popen(buf, "w");
00296 if (fp != NULL) {
00297 fprintf(fp, "0\n");
00298 fflush(fp);
00299 }
00300 }
00301 else if (curr == cmax) {
00302 if (fp != NULL) {
00303 fprintf(fp, "100\n");
00304 pclose(fp);
00305 fp = NULL;
00306 }
00307 }
00308 else {
00309 a = (curr * 100) / cmax;
00310 if (fp != NULL) {
00311 fprintf(fp, "%ld\n", a);
00312 fflush(fp);
00313 }
00314 }
00315 break;
00316 }
00317 }
00318
00319
00320
00321
00322
00323
00324
00325
00326 void install_init_scripts(void)
00327 {
00328 char question[1024];
00329 char buf[256];
00330 char http_port[128];
00331 #ifdef HAVE_OPENSSL
00332 char https_port[128];
00333 #endif
00334 char hostname[128];
00335 char portname[128];
00336 char command[SIZ];
00337 struct utsname my_utsname;
00338 struct stat etcinitd;
00339 FILE *fp;
00340 char *initfile = "/etc/init.d/webcit";
00341
00342
00343 snprintf(question, sizeof question,
00344 "Would you like to automatically start WebCit at boot?"
00345 );
00346 if (yesno(question, 1) == 0)
00347 return;
00348
00349
00350 sprintf(http_port, "2000");
00351 #ifdef HAVE_OPENSSL
00352 sprintf(https_port, "443");
00353 #endif
00354 sprintf(hostname, "uds");
00355 sprintf(portname, "/usr/local/citadel");
00356
00357
00358
00359
00360
00361 if ((stat("/etc/init.d/", &etcinitd) == -1) &&
00362 (errno == ENOENT))
00363 {
00364 if ((stat("/etc/rc.d/init.d/", &etcinitd) == -1) &&
00365 (errno == ENOENT))
00366 initfile = PREFIX"/webcit.init";
00367 else
00368 initfile = "/etc/rc.d/init.d/webcit";
00369 }
00370
00371 fp = fopen(initfile, "r");
00372 if (fp != NULL) {
00373 while (fgets(buf, sizeof buf, fp) != NULL) {
00374 if (strlen(buf) > 0) {
00375 buf[strlen(buf)-1] = 0;
00376 }
00377 if (!strncasecmp(buf, "HTTP_PORT=", 10)) {
00378 safestrncpy(http_port, &buf[10], sizeof http_port);
00379 }
00380 #ifdef HAVE_OPENSSL
00381 if (!strncasecmp(buf, "HTTPS_PORT=", 11)) {
00382 safestrncpy(https_port, &buf[11], sizeof https_port);
00383 }
00384 #endif
00385 if (!strncasecmp(buf, "CTDL_HOSTNAME=", 14)) {
00386 safestrncpy(hostname, &buf[14], sizeof hostname);
00387 }
00388 if (!strncasecmp(buf, "CTDL_PORTNAME=", 14)) {
00389 safestrncpy(portname, &buf[14], sizeof portname);
00390 }
00391 }
00392 fclose(fp);
00393 }
00394
00395
00396 snprintf(question, sizeof question,
00397 "On which port do you want WebCit to listen for HTTP "
00398 "requests?\n\nYou can use the standard port (80) if you are "
00399 "not running another\nweb server (such as Apache), otherwise "
00400 "select another port.");
00401 set_value(question, http_port);
00402 uname(&my_utsname);
00403 sprintf(suggested_url, "http://%s:%s/", my_utsname.nodename, http_port);
00404
00405 #ifdef HAVE_OPENSSL
00406 snprintf(question, sizeof question,
00407 "On which port do you want WebCit to listen for HTTPS "
00408 "requests?\n\nYou can use the standard port (443) if you are "
00409 "not running another\nweb server (such as Apache), otherwise "
00410 "select another port.");
00411 set_value(question, https_port);
00412 #endif
00413
00414
00415 if ( (using_web_installer) && (getenv("CITADEL") != NULL) ) {
00416 strcpy(hostname, "uds");
00417 strcpy(portname, getenv("CITADEL"));
00418 }
00419 else {
00420 snprintf(question, sizeof question,
00421 "Is the Citadel service running on the same host as WebCit?");
00422 if (yesno(question, ((!strcasecmp(hostname, "uds")) ? 1 : 0))) {
00423 strcpy(hostname, "uds");
00424 if (atoi(portname) != 0) strcpy(portname, "/usr/local/citadel");
00425 set_value("In what directory is Citadel installed?", portname);
00426 }
00427 else {
00428 if (!strcasecmp(hostname, "uds")) strcpy(hostname, "127.0.0.1");
00429 if (atoi(portname) == 0) strcpy(portname, "504");
00430 set_value("Enter the host name or IP address of your "
00431 "Citadel server.", hostname);
00432 set_value("Enter the port number on which Citadel is "
00433 "running (usually 504)", portname);
00434 }
00435 }
00436
00437
00438 fp = fopen(initfile, "w");
00439
00440 fprintf(fp, "#!/bin/sh\n"
00441 "\n"
00442 "WEBCIT_DIR=%s\n", setup_directory);
00443 fprintf(fp, "HTTP_PORT=%s\n", http_port);
00444 #ifdef HAVE_OPENSSL
00445 fprintf(fp, "HTTPS_PORT=%s\n", https_port);
00446 #endif
00447 fprintf(fp, "CTDL_HOSTNAME=%s\n", hostname);
00448 fprintf(fp, "CTDL_PORTNAME=%s\n", portname);
00449 fprintf(fp, "\n"
00450 "\n"
00451 "case \"$1\" in\n"
00452 "\n"
00453 "start) echo -n \"Starting WebCit... \"\n"
00454 " if $WEBCIT_DIR/webserver "
00455 "-D/var/run/webcit.pid "
00456 "-p$HTTP_PORT $CTDL_HOSTNAME $CTDL_PORTNAME\n"
00457 " then\n"
00458 " echo \"ok\"\n"
00459 " else\n"
00460 " echo \"failed\"\n"
00461 " fi\n");
00462 #ifdef HAVE_OPENSSL
00463 fprintf(fp, " echo -n \"Starting WebCit SSL... \"\n"
00464 " if $WEBCIT_DIR/webserver "
00465 "-D/var/run/webcit-ssl.pid "
00466 "-s -p$HTTPS_PORT $CTDL_HOSTNAME $CTDL_PORTNAME\n"
00467 " then\n"
00468 " echo \"ok\"\n"
00469 " else\n"
00470 " echo \"failed\"\n"
00471 " fi\n");
00472 #endif
00473 fprintf(fp, " ;;\n"
00474 "stop) echo -n \"Stopping WebCit... \"\n"
00475 " if kill `cat /var/run/webcit.pid 2>/dev/null` 2>/dev/null\n"
00476 " then\n"
00477 " echo \"ok\"\n"
00478 " else\n"
00479 " echo \"failed\"\n"
00480 " fi\n"
00481 " rm -f /var/run/webcit.pid 2>/dev/null\n");
00482 #ifdef HAVE_OPENSSL
00483 fprintf(fp, " echo -n \"Stopping WebCit SSL... \"\n"
00484 " if kill `cat /var/run/webcit-ssl.pid 2>/dev/null` 2>/dev/null\n"
00485 " then\n"
00486 " echo \"ok\"\n"
00487 " else\n"
00488 " echo \"failed\"\n"
00489 " fi\n"
00490 " rm -f /var/run/webcit-ssl.pid 2>/dev/null\n");
00491 #endif
00492 fprintf(fp, " ;;\n"
00493 "restart) $0 stop\n"
00494 " $0 start\n"
00495 " ;;\n"
00496 "*) echo \"Usage: $0 {start|stop|restart}\"\n"
00497 " exit 1\n"
00498 " ;;\n"
00499 "esac\n"
00500 );
00501
00502 fclose(fp);
00503 chmod(initfile, 0755);
00504
00505
00506 system("/bin/rm -f /etc/rc?.d/[SK]??webcit 2>/dev/null");
00507 snprintf(command, sizeof(command), "for x in 2 3 4 5 ; do [ -d /etc/rc$x.d ] && ln -s %s /etc/rc$x.d/S84webcit ; done 2>/dev/null", initfile);
00508 system(command);
00509 snprintf(command, sizeof(command), "for x in 0 6 S; do [ -d /etc/rc$x.d ] && ln -s %s /etc/rc$x.d/K15webcit ; done 2>/dev/null", initfile);
00510 system(command);
00511
00512 }
00513
00514
00515
00516
00517
00518
00519
00520 int discover_ui(void)
00521 {
00522
00523
00524 if (getenv("CTDL_DIALOG") != NULL) {
00525 return UI_DIALOG;
00526 }
00527
00528 return UI_TEXT;
00529 }
00530
00531
00532
00533
00534
00535 int main(int argc, char *argv[])
00536 {
00537 int a;
00538 char aaa[256];
00539 int info_only = 0;
00540 strcpy(suggested_url, "http://<your_host_name>:<port>/");
00541
00542
00543 setup_type = (-1);
00544
00545
00546 if (getenv("CITADEL_INSTALLER") != NULL) {
00547 using_web_installer = 1;
00548 }
00549
00550
00551 for (a = 0; a < argc; ++a) {
00552 if (!strncmp(argv[a], "-u", 2)) {
00553 strcpy(aaa, argv[a]);
00554 strcpy(aaa, &aaa[2]);
00555 setup_type = atoi(aaa);
00556 }
00557 if (!strcmp(argv[a], "-i")) {
00558 info_only = 1;
00559 }
00560 if (!strcmp(argv[a], "-q")) {
00561 setup_type = UI_SILENT;
00562 }
00563 }
00564
00565
00566
00567
00568
00569 if (setup_type < 0) {
00570 setup_type = discover_ui();
00571 }
00572 if (info_only == 1) {
00573 important_message("WebCit Setup", "Welcome to WebCit setup");
00574 cleanup(0);
00575 }
00576
00577
00578 strcpy(setup_directory, PREFIX);
00579 if ( (using_web_installer) && (getenv("WEBCIT") != NULL) ) {
00580 strcpy(setup_directory, getenv("WEBCIT"));
00581 }
00582 else {
00583 set_value("In what directory is WebCit installed?",
00584 setup_directory);
00585 }
00586 if (chdir(setup_directory) != 0) {
00587 important_message("WebCit Setup",
00588 "The directory you specified does not exist.");
00589 cleanup(errno);
00590 }
00591
00592
00593
00594
00595
00596 progress("Removing obsolete /etc/inittab entries...", 0, 1);
00597 delete_the_old_way();
00598 progress("Removing obsolete /etc/inittab entries...", 1, 1);
00599
00600
00601 switch (setup_type) {
00602
00603 case UI_TEXT:
00604 printf("\n\n\n"
00605 " *** WebCit setup program ***\n\n");
00606 break;
00607
00608 }
00609
00610
00611
00612
00613 if (!access("/var/run", W_OK)) {
00614 install_init_scripts();
00615
00616 if (!access("/etc/init.d/webcit", X_OK)) {
00617 system("/etc/init.d/webcit stop");
00618 system("/etc/init.d/webcit start");
00619 }
00620
00621 sprintf(aaa,
00622 "Setup is finished. You may now log in.\n"
00623 "Point your web browser at %s\n", suggested_url
00624 );
00625 important_message("Setup finished", aaa);
00626 }
00627
00628 else {
00629 important_message("Setup finished",
00630 "Setup is finished. You may now start the server.");
00631 }
00632
00633 cleanup(0);
00634 return 0;
00635 }