X-Git-Url: https://code.citadel.org/?a=blobdiff_plain;f=webcit%2Fsetup.c;h=ebac8d2ca193ba5dae5a07c0cd99456a0a397fbe;hb=e21b689461215d6012ff62d76c2da73d4ffeb33a;hp=4478728c6f1021120d31db98cb0f21c4ed33dfdd;hpb=9ab2858c5a9fe3bee998f3345528e9e48651c38a;p=citadel.git diff --git a/webcit/setup.c b/webcit/setup.c index 4478728c6..ebac8d2ca 100644 --- a/webcit/setup.c +++ b/webcit/setup.c @@ -1,49 +1,54 @@ /* - * $Id$ - * * WebCit setup utility * * (This is basically just an install wizard. It's not required.) - * */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - +#include "sysdep.h" #include "webcit.h" - -#ifdef HAVE_NEWT -#include -#endif +#include "webserver.h" #define UI_TEXT 0 /* Default setup type -- text only */ +#define UI_DIALOG 2 /* Use the 'dialog' program */ #define UI_SILENT 3 /* Silent running, for use in scripts */ -#define UI_NEWT 4 /* Use the "newt" window library */ int setup_type; char setup_directory[SIZ]; -char init_entry[SIZ]; int using_web_installer = 0; +char suggested_url[SIZ]; + +/* some copies... +int syslog(int loglevel, const char *format, ...){return 0;} */ +void wc_printf(const char *format,...){} + +void RegisterNS(const char *NSName, long len, + int nMinArgs, + int nMaxArgs, + WCHandlerFunc HandlerFunc, + WCPreevalFunc PreEvalFunc, + int ContextRequired){} +void StrBufAppendTemplateStr(StrBuf *Target, + WCTemplputParams *TP, + const char *Source, + int FormatTypeIndex){} +void RegisterHeaderHandler(const char *Name, long Len, Header_Evaluator F){} +pthread_key_t MyConKey; + +#ifdef ENABLE_NLS + +#ifdef HAVE_USELOCALE +int localeoffset = 1; +#else +int localeoffset = 0; +#endif - +#endif /* - * Set an entry in inittab to the desired state + * Delete an entry from /etc/inittab */ -void set_init_entry(char *which_entry, char *new_state) { +void delete_init_entry(char *which_entry) +{ char *inittab = NULL; FILE *fp; char buf[SIZ]; @@ -61,15 +66,13 @@ void set_init_entry(char *which_entry, char *new_state) { while(fgets(buf, sizeof buf, fp) != NULL) { if (num_tokens(buf, ':') == 4) { - extract_token(entry, buf, 0, ':'); - extract_token(levels, buf, 1, ':'); - extract_token(state, buf, 2, ':'); - extract_token(prog, buf, 3, ':'); /* includes 0x0a LF */ + extract_token(entry, buf, 0, ':', sizeof entry); + extract_token(levels, buf, 1, ':', sizeof levels); + extract_token(state, buf, 2, ':', sizeof state); + extract_token(prog, buf, 3, ':', sizeof prog); /* includes 0x0a LF */ if (!strcmp(entry, which_entry)) { - strcpy(state, new_state); - sprintf(buf, "%s:%s:%s:%s", - entry, levels, state, prog); + strcpy(state, "off"); /* disable it */ } } @@ -95,23 +98,26 @@ void set_init_entry(char *which_entry, char *new_state) { /* - * Shut down the Citadel service if necessary, during setup. + * Remove any /etc/inittab entries for webcit, because we don't + * start it that way anymore. */ -void shutdown_service(void) { +void delete_the_old_way(void) { FILE *infp; - char buf[SIZ]; - char looking_for[SIZ]; + char buf[1024]; + char looking_for[1024]; int have_entry = 0; - char entry[SIZ]; - char prog[SIZ]; + char entry[1024]; + char prog[1024]; + char init_entry[1024]; + strcpy(init_entry, ""); - /* Determine the fully qualified path name of webserver */ - snprintf(looking_for, sizeof looking_for, "%s/webserver ", WEBCITDIR); + /* Determine the fully qualified path name of webcit */ + snprintf(looking_for, sizeof looking_for, "%s/webcit ", setup_directory); /* Pound through /etc/inittab line by line. Set have_entry to 1 if - * an entry is found which we believe starts webserver. + * an entry is found which we believe starts webcit. */ infp = fopen("/etc/inittab", "r"); if (infp == NULL) { @@ -119,8 +125,8 @@ void shutdown_service(void) { } else { while (fgets(buf, sizeof buf, infp) != NULL) { buf[strlen(buf) - 1] = 0; - extract_token(entry, buf, 0, ':'); - extract_token(prog, buf, 3, ':'); + extract_token(entry, buf, 0, ':', sizeof entry); + extract_token(prog, buf, 3, ':', sizeof prog); if (!strncasecmp(prog, looking_for, strlen(looking_for))) { ++have_entry; @@ -133,28 +139,13 @@ void shutdown_service(void) { /* Bail out if there's nothing to do. */ if (!have_entry) return; - set_init_entry(init_entry, "off"); -} - - -/* - * Start the Citadel service. - */ -void start_the_service(void) { - if (strlen(init_entry) > 0) { - set_init_entry(init_entry, "respawn"); - } + delete_init_entry(init_entry); } void cleanup(int exitcode) { -#ifdef HAVE_NEWT - newtCls(); - newtRefresh(); - newtFinished(); -#endif exit(exitcode); } @@ -169,68 +160,62 @@ void title(char *text) -int yesno(char *question) + +int yesno(char *question, int default_value) { -#ifdef HAVE_NEWT - newtComponent form = NULL; - newtComponent yesbutton = NULL; - newtComponent nobutton = NULL; int i = 0; -#endif int answer = 0; - char buf[SIZ]; + char buf[SIZ] = ""; switch (setup_type) { case UI_TEXT: do { - printf("%s\nYes/No --> ", question); - fgets(buf, sizeof buf, stdin); - answer = tolower(buf[0]); - if (answer == 'y') - answer = 1; - else if (answer == 'n') - answer = 0; + printf("%s\nYes/No [%s] --> ", + question, + ( default_value ? "Yes" : "No" ) + ); + if (fgets(buf, sizeof buf, stdin)) + { + answer = tolower(buf[0]); + if ((buf[0]==0) || (buf[0]==13) || (buf[0]==10)) + answer = default_value; + else if (answer == 'y') + answer = 1; + else if (answer == 'n') + answer = 0; + } + } while ((answer < 0) || (answer > 1)); break; -#ifdef HAVE_NEWT - case UI_NEWT: - newtCenteredWindow(76, 10, "Question"); - form = newtForm(NULL, NULL, 0); - for (i=0; i%s", + getenv("CTDL_DIALOG"), + prompt, + str, + dialog_result); + system(buf); + fp = fopen(dialog_result, "r"); + if (fp != NULL) { + if (fgets(str, sizeof buf, fp)){ + if (str[strlen(str)-1] == 10) { + str[strlen(str)-1] = 0; + } + } + fclose(fp); + unlink(dialog_result); } - newtFormAddComponent(form, newtEntry(1, 8, str, 74, &result, - NEWT_FLAG_RETURNEXIT)); - newtRunForm(form); - strcpy(str, result); - - newtPopWindow(); - newtFormDestroy(form); + break; -#endif } } -void important_message(char *title, char *msgtext) +extern const char *AvailLang[]; +int GetLocalePrefs(void) { -#ifdef HAVE_NEWT - newtComponent form = NULL; + int nLocales; + StrBuf *Buf; + char buf[SIZ]; + char dialog_result[PATH_MAX]; + FILE *fp; int i = 0; + int offs = 0; + + nLocales = 0; + while (!IsEmptyStr(AvailLang[nLocales])) + nLocales++; + + Buf = NewStrBuf(); + + StrBufAppendBufPlain(Buf, HKEY("Select the locale webcit should use : \n"), 0); +#ifdef HAVE_USELOCALE + StrBufAppendBufPlain(Buf, HKEY(" 0 Let the user select it at the login prompt (default)\n"), 0); + offs ++; #endif + for (i = 0; i < nLocales; i++) { + StrBufAppendPrintf(Buf, " %ld: %s\n", i + offs, AvailLang[i]); + + } + + switch (setup_type) { + case UI_TEXT: + title("WebCit setup"); + printf("\n%s\n", ChrPtr(Buf)); + printf("This is currently set to:\n%ld\n", 0L); + printf("Enter new value or press return to leave unchanged:\n"); + if (fgets(buf, sizeof buf, stdin)) + return atoi(buf); + break; + + case UI_DIALOG: + CtdlMakeTempFileName(dialog_result, sizeof dialog_result); + sprintf(buf, "exec %s --inputbox '%s' 19 72 '%ld' 2>%s", + getenv("CTDL_DIALOG"), + ChrPtr(Buf), + 0L, + dialog_result); + system(buf); + fp = fopen(dialog_result, "r"); + if (fp != NULL) { + char *str = &buf[0]; + if (fgets(str, sizeof buf, fp)){ + if (str[strlen(str)-1] == 10) { + str[strlen(str)-1] = 0; + } + } + fclose(fp); + unlink(dialog_result); + return atoi(buf); + } + break; + + } + return 0; +} + +void important_message(char *title, char *msgtext) +{ char buf[SIZ]; switch (setup_type) { @@ -281,24 +328,15 @@ void important_message(char *title, char *msgtext) 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"); printf(" %s \n\n%s\n\n", title, msgtext); printf("Press return to continue..."); - fgets(buf, sizeof buf, stdin); + if (fgets(buf, sizeof buf, stdin)); break; -#ifdef HAVE_NEWT - case UI_NEWT: - newtCenteredWindow(76, 10, title); - form = newtForm(NULL, NULL, 0); - for (i=0; i 0) && (curr <= cmax)) { - newtScaleSet(scale, curr); - newtRefresh(); + sprintf(buf, "exec %s --gauge '%s' 7 72 0", + getenv("CTDL_DIALOG"), + text); + fp = popen(buf, "w"); + if (fp != NULL) { + fprintf(fp, "0\n"); + fflush(fp); + } + } + else if (curr == cmax) { + if (fp != NULL) { + fprintf(fp, "100\n"); + pclose(fp); + fp = NULL; + } } - if (curr == cmax) { - newtFormDestroy(form); - newtPopWindow(); - newtRefresh(); + else { + a = (curr * 100) / cmax; + if (fp != NULL) { + fprintf(fp, "%ld\n", a); + fflush(fp); + } } break; -#endif - } } @@ -376,52 +410,113 @@ void progress(char *text, long int curr, long int cmax) /* - * check_inittab_entry() -- Make sure "webserver" is in /etc/inittab + * install_init_scripts() -- Create and deploy SysV init scripts. * */ -void check_inittab_entry(void) +void install_init_scripts(void) { - FILE *infp; - char buf[SIZ]; - char looking_for[SIZ]; - char question[SIZ]; - char entryname[5]; +#ifdef ENABLE_NLS + int localechoice; +#endif + char question[1024]; + char buf[256]; char http_port[128]; +#ifdef HAVE_OPENSSL char https_port[128]; +#endif char hostname[128]; char portname[128]; + char command[SIZ]; + struct utsname my_utsname; + struct stat etcinitd; + FILE *fp; + char *initfile = "/etc/init.d/webcit"; - /* Determine the fully qualified path name of webserver */ - snprintf(looking_for, sizeof looking_for, "%s/webserver ", WEBCITDIR); - - /* If there's already an entry, then we have nothing left to do. */ - if (strlen(init_entry) > 0) { - return; + fp = fopen(initfile, "r"); + if (fp != NULL) { + if (yesno("WebCit already appears to be configured to start at boot.\n" + "Would you like to keep your boot configuration as is?\n", 1) == 1) { + return; + } + fclose(fp); + } /* Otherwise, prompt the user to create an entry. */ snprintf(question, sizeof question, - "There is no '%s' entry in /etc/inittab.\n" - "Would you like to add one?", - looking_for); - if (yesno(question) == 0) + "Would you like to automatically start WebCit at boot?" + ); + if (yesno(question, 1) == 0) return; - snprintf(question, sizeof question, - "On which port do you want WebCit to listen for HTTP " - "requests?\n\nYou can use the standard port (80) if you are " - "not running another\nweb server (such as Apache), otherwise " - "select another port."); + +#ifdef ENABLE_NLS + + localechoice = GetLocalePrefs(); + +#endif + /* Defaults */ sprintf(http_port, "2000"); +#ifdef HAVE_OPENSSL + sprintf(https_port, "443"); +#endif + sprintf(hostname, "uds"); + sprintf(portname, "/usr/local/citadel"); + + /* This is a very hackish way of learning the port numbers used + * in a previous install, if we are upgrading: read them out of + * the existing init script. + */ + if ((stat("/etc/init.d/", &etcinitd) == -1) && + (errno == ENOENT)) + { + if ((stat("/etc/rc.d/init.d/", &etcinitd) == -1) && + (errno == ENOENT)) + initfile = WEBCITDIR"/webcit.init"; + else + initfile = "/etc/rc.d/init.d/webcit"; + } + + fp = fopen(initfile, "r"); + if (fp != NULL) { + while (fgets(buf, sizeof buf, fp) != NULL) { + if (strlen(buf) > 0) { + buf[strlen(buf)-1] = 0; /* strip trailing cr */ + } + if (!strncasecmp(buf, "HTTP_PORT=", 10)) { + safestrncpy(http_port, &buf[10], sizeof http_port); + } +#ifdef HAVE_OPENSSL + if (!strncasecmp(buf, "HTTPS_PORT=", 11)) { + safestrncpy(https_port, &buf[11], sizeof https_port); + } +#endif + if (!strncasecmp(buf, "CTDL_HOSTNAME=", 14)) { + safestrncpy(hostname, &buf[14], sizeof hostname); + } + if (!strncasecmp(buf, "CTDL_PORTNAME=", 14)) { + safestrncpy(portname, &buf[14], sizeof portname); + } + } + fclose(fp); + } + + /* Now ask for the port numbers */ + snprintf(question, sizeof question, + "On which port do you want WebCit to listen for HTTP " + "requests?\n\nYou can use the standard port (80) if you are " + "not running another\nweb server (such as Apache), otherwise " + "select another port."); set_value(question, http_port); + uname(&my_utsname); + sprintf(suggested_url, "http://%s:%s/", my_utsname.nodename, http_port); #ifdef HAVE_OPENSSL snprintf(question, sizeof question, - "On which port do you want WebCit to listen for HTTPS " - "requests?\n\nYou can use the standard port (443) if you are " - "not running another\nweb server (such as Apache), otherwise " - "select another port."); - sprintf(https_port, "443"); + "On which port do you want WebCit to listen for HTTPS " + "requests?\n\nYou can use the standard port (443) if you are " + "not running another\nweb server (such as Apache), otherwise " + "select another port."); set_value(question, https_port); #endif @@ -432,57 +527,117 @@ void check_inittab_entry(void) } else { snprintf(question, sizeof question, - "Is the Citadel service running on the same host as WebCit?"); - if (yesno(question)) { - sprintf(hostname, "uds"); - sprintf(portname, "/usr/local/citadel"); + "Is the Citadel service running on the same host as WebCit?"); + if (yesno(question, ((!strcasecmp(hostname, "uds")) ? 1 : 0))) { + strcpy(hostname, "uds"); + if (atoi(portname) != 0) strcpy(portname, "/usr/local/citadel"); set_value("In what directory is Citadel installed?", portname); } else { - sprintf(hostname, "127.0.0.1"); - sprintf(portname, "504"); + if (!strcasecmp(hostname, "uds")) strcpy(hostname, "127.0.0.1"); + if (atoi(portname) == 0) strcpy(portname, "504"); set_value("Enter the host name or IP address of your " - "Citadel server.", hostname); + "Citadel server.", hostname); set_value("Enter the port number on which Citadel is " - "running (usually 504)", portname); + "running (usually 504)", portname); } } - /* Generate unique entry names for /etc/inittab */ - snprintf(entryname, sizeof entryname, "c0"); - do { - ++entryname[1]; - if (entryname[1] > '9') { - entryname[1] = 0; - ++entryname[0]; - if (entryname[0] > 'z') { - display_error( - "Can't generate a unique entry name"); - return; - } - } - snprintf(buf, sizeof buf, - "grep %s: /etc/inittab >/dev/null 2>&1", entryname); - } while (system(buf) == 0); - - /* Now write it out to /etc/inittab */ - infp = fopen("/etc/inittab", "a"); - if (infp == NULL) { - display_error(strerror(errno)); - } else { - fprintf(infp, "# Start the WebCit server...\n"); - fprintf(infp, "h%s:2345:respawn:%s -p%s %s %s\n", - entryname, looking_for, - http_port, hostname, portname); + fp = fopen(initfile, "w"); + + fprintf(fp, "#!/bin/sh\n" + "\n" + "# uncomment this to create coredumps as described in\n" + "# http://www.citadel.org/doku.php/faq:mastering_your_os:gdb#how.do.i.make.my.system.produce.core-files\n" + "# ulimit -c unlimited\n" + "WEBCIT_DIR=%s\n", setup_directory); + fprintf(fp, "HTTP_PORT=%s\n", http_port); #ifdef HAVE_OPENSSL - fprintf(infp, "s%s:2345:respawn:%s -p%s -s %s %s\n", - entryname, looking_for, - https_port, hostname, portname); + fprintf(fp, "HTTPS_PORT=%s\n", https_port); #endif - fclose(infp); - strcpy(init_entry, entryname); + fprintf(fp, "CTDL_HOSTNAME=%s\n", hostname); + fprintf(fp, "CTDL_PORTNAME=%s\n", portname); + +#ifdef ENABLE_NLS + + if (localechoice == 0) { +#ifdef HAVE_USELOCALE + fprintf(fp, "unset LANG\n"); +#else + fprintf(fp, "export WEBCIT_LANG=c\n"); +#endif + } + else { + fprintf(fp, "export WEBCIT_LANG=%s\n", AvailLang[localechoice - localeoffset]); + } +#else + fprintf(fp, "# your system doesn't support locales\n"); +#endif + fprintf(fp, "\n" + "\n" + "case \"$1\" in\n" + "\n" + "start) echo -n \"Starting WebCit... \"\n" + " if $WEBCIT_DIR/webcit " + "-D/var/run/webcit.pid " + "-p$HTTP_PORT $CTDL_HOSTNAME $CTDL_PORTNAME\n" + " then\n" + " echo \"ok\"\n" + " else\n" + " echo \"failed\"\n" + " fi\n"); +#ifdef HAVE_OPENSSL + fprintf(fp, " echo -n \"Starting WebCit SSL... \"\n" + " if $WEBCIT_DIR/webcit " + "-D/var/run/webcit-ssl.pid " + "-s -p$HTTPS_PORT $CTDL_HOSTNAME $CTDL_PORTNAME\n" + " then\n" + " echo \"ok\"\n" + " else\n" + " echo \"failed\"\n" + " fi\n"); +#endif + fprintf(fp, " ;;\n" + "stop) echo -n \"Stopping WebCit... \"\n" + " if kill `cat /var/run/webcit.pid 2>/dev/null` 2>/dev/null\n" + " then\n" + " echo \"ok\"\n" + " else\n" + " echo \"failed\"\n" + " fi\n" + " rm -f /var/run/webcit.pid 2>/dev/null\n"); +#ifdef HAVE_OPENSSL + fprintf(fp, " echo -n \"Stopping WebCit SSL... \"\n" + " if kill `cat /var/run/webcit-ssl.pid 2>/dev/null` 2>/dev/null\n" + " then\n" + " echo \"ok\"\n" + " else\n" + " echo \"failed\"\n" + " fi\n" + " rm -f /var/run/webcit-ssl.pid 2>/dev/null\n"); +#endif + fprintf(fp, " ;;\n" + "restart) $0 stop\n" + " $0 start\n" + " ;;\n" + "*) echo \"Usage: $0 {start|stop|restart}\"\n" + " exit 1\n" + " ;;\n" + "esac\n" + ); + + fclose(fp); + chmod(initfile, 0755); + + /* Set up the run levels. */ + system("/bin/rm -f /etc/rc?.d/[SK]??webcit 2>/dev/null"); + 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); + system(command); + 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); + system(command); + } @@ -494,12 +649,11 @@ void check_inittab_entry(void) int discover_ui(void) { -#ifdef HAVE_NEWT - newtInit(); - newtCls(); - newtDrawRootText(0, 0, "WebCit Setup"); - return UI_NEWT; -#endif + /* Use "dialog" if we have it */ + if (getenv("CTDL_DIALOG") != NULL) { + return UI_DIALOG; + } + return UI_TEXT; } @@ -510,9 +664,11 @@ int discover_ui(void) int main(int argc, char *argv[]) { int a; - char aaa[128]; + char aaa[256]; int info_only = 0; + strcpy(suggested_url, "http://:/"); + /* set an invalid setup type */ setup_type = (-1); @@ -563,12 +719,13 @@ int main(int argc, char *argv[]) cleanup(errno); } - /* See if we need to shut down the WebCit service. */ - for (a=0; a<=3; ++a) { - progress("Shutting down the WebCit service...", a, 3); - if (a == 0) shutdown_service(); - sleep(1); - } + /* + * We used to start WebCit by putting it directly into /etc/inittab. + * Since some systems are moving away from init, we can't do this anymore. + */ + progress("Removing obsolete /etc/inittab entries...", 0, 1); + delete_the_old_way(); + progress("Removing obsolete /etc/inittab entries...", 1, 1); /* Now begin. */ switch (setup_type) { @@ -580,18 +737,24 @@ int main(int argc, char *argv[]) } - check_inittab_entry(); /* Check /etc/inittab */ + /* + * If we're running on SysV, install init scripts. + */ + if (!access("/var/run", W_OK)) { + install_init_scripts(); - /* See if we can start the WebCit service. */ - if (strlen(init_entry) > 0) { - for (a=0; a<=3; ++a) { - progress("Starting the WebCit service...", a, 3); - if (a == 0) start_the_service(); - sleep(1); + if (!access("/etc/init.d/webcit", X_OK)) { + system("/etc/init.d/webcit stop"); + system("/etc/init.d/webcit start"); } - important_message("Setup finished", - "Setup is finished. You may now log in."); + + sprintf(aaa, + "Setup is finished. You may now log in.\n" + "Point your web browser at %s\n", suggested_url + ); + important_message("Setup finished", aaa); } + else { important_message("Setup finished", "Setup is finished. You may now start the server.");