From 25bdf679e0136c2cfdf0dbfd7b5ba23d95a2acbd Mon Sep 17 00:00:00 2001 From: Art Cancro Date: Mon, 27 Nov 2006 04:57:20 +0000 Subject: [PATCH] * setup now deletes old inittab entries if they were present * setup now writes /etc/init.d/webcit if running on an appropriate system --- webcit/Makefile.in | 8 +- webcit/ctdlsvc.c | 55 ++++++++++++-- webcit/setup.c | 183 ++++++++++++++++++++------------------------- 3 files changed, 135 insertions(+), 111 deletions(-) diff --git a/webcit/Makefile.in b/webcit/Makefile.in index 64d7c10c0..0512e25ce 100644 --- a/webcit/Makefile.in +++ b/webcit/Makefile.in @@ -21,13 +21,13 @@ SUBDIRS=$(LIB_SUBDIRS) $(PROG_SUBDIRS) # End of configuration section -all: all-progs-recursive webserver setup +all: all-progs-recursive webserver setup ctdlsvc .SUFFIXES: .cpp .c .o clean: - rm -f *.o webcit webserver + rm -f *.o webcit webserver ctdlsvc rm -fr locale/* distclean: clean @@ -39,6 +39,9 @@ setup: setup.o tools.o $(CC) setup.o tools.o \ $(LIBOBJS) $(LIBS) $(LDFLAGS) $(SETUP_LIBS) -o setup +ctdlsvc: ctdlsvc.o + $(CC) ctdlsvc.o -o ctdlsvc + webserver: webserver.o context_loop.o tools.o ical_dezonify.o \ cookie_conversion.o locate_host.o floors.o summary.o \ webcit.o auth.o tcp_sockets.o mainmenu.o serv_func.o who.o \ @@ -93,6 +96,7 @@ install: for i in \ webserver \ setup \ + ctdlsvc \ `find static -type f | grep -v .svn` \ `find tiny_mce -type f | grep -v .svn` \ `find locale -type f | grep -v .svn` \ diff --git a/webcit/ctdlsvc.c b/webcit/ctdlsvc.c index 69c5277a9..865efc298 100644 --- a/webcit/ctdlsvc.c +++ b/webcit/ctdlsvc.c @@ -1,8 +1,8 @@ /* * $Id: $ * - * This is just a quick little hack to start a program and automatically - * restart it if it exits with a nonzero exit status. + * This is just a quick little hack to start a program in the background, + * and automatically restart it if it exits with a nonzero exit status. * */ @@ -12,36 +12,75 @@ #include #include #include +#include +char *pidfilename = NULL; +pid_t current_child = 0; + +RETSIGTYPE graceful_shutdown(int signum) { + kill(current_child, signum); + if (pidfilename != NULL) { + unlink(pidfilename); + } + exit(0); +} + int main(int argc, char **argv) { pid_t child = 0; int status = 0; + FILE *fp; + + --argc; + ++argv; + pidfilename = argv[0]; --argc; ++argv; + if (access(argv[0], X_OK)) { + fprintf(stderr, "%s: cannot execute\n", argv[0]); + exit(1); + } + + close(1); + close(2); + signal(SIGHUP, SIG_IGN); + signal(SIGINT, SIG_IGN); + signal(SIGQUIT, SIG_IGN); + + child = fork(); + if (child != 0) { + fp = fopen(pidfilename, "w"); + if (fp != NULL) { + fprintf(fp, "%d\n", child); + fclose(fp); + } + exit(0); + } + do { - child = fork(); + current_child = fork(); + + signal(SIGTERM, graceful_shutdown); - if (child < 0) { + if (current_child < 0) { perror("fork"); exit(errno); } - else if (child == 0) { + else if (current_child == 0) { exit(execvp(argv[0], &argv[0])); } else { - printf("%s: started. pid = %d\n", argv[0], child); - waitpid(child, &status, 0); - printf("Exit code %d\n", status); + waitpid(current_child, &status, 0); } } while (status != 0); + unlink(pidfilename); exit(0); } diff --git a/webcit/setup.c b/webcit/setup.c index f11a91767..4984e34e8 100644 --- a/webcit/setup.c +++ b/webcit/setup.c @@ -24,14 +24,14 @@ int setup_type; char setup_directory[SIZ]; -char init_entry[SIZ]; int using_web_installer = 0; char suggested_url[SIZ]; /* * Set an entry in inittab to the desired state */ -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]; @@ -55,9 +55,7 @@ void set_init_entry(char *which_entry, char *new_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); + buf[0] = 0; /* delete it */ } } @@ -83,15 +81,18 @@ 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, ""); @@ -121,17 +122,7 @@ 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); } @@ -435,16 +426,12 @@ void progress(char *text, long int curr, long int cmax) /* - * check_inittab_entry() -- Make sure "webserver" is in /etc/inittab + * install_init_scripts() -- Make sure "webserver" is in /etc/inittab * */ -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]; char http_port[128]; #ifdef HAVE_OPENSSL char https_port[128]; @@ -453,19 +440,12 @@ void check_inittab_entry(void) char portname[128]; struct utsname my_utsname; - /* Determine the fully qualified path name of webserver */ - snprintf(looking_for, sizeof looking_for, "%s/webserver", setup_directory); - - /* If there's already an entry, then we have nothing left to do. */ - if (strlen(init_entry) > 0) { - return; - } + FILE *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); + "Would you like to automatically start WebCit at boot?" + ); if (yesno(question) == 0) return; @@ -474,7 +454,7 @@ void check_inittab_entry(void) "requests?\n\nYou can use the standard port (80) if you are " "not running another\nweb server (such as Apache), otherwise " "select another port."); - sprintf(http_port, "2000"); + sprintf(http_port, "80"); set_value(question, http_port); uname(&my_utsname); sprintf(suggested_url, "http://%s:%s/", my_utsname.nodename, http_port); @@ -512,41 +492,45 @@ void check_inittab_entry(void) } } - /* 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); -#ifdef HAVE_OPENSSL - fprintf(infp, "s%s:2345:respawn:%s -p%s -s %s %s\n", - entryname, looking_for, - https_port, hostname, portname); -#endif - fclose(infp); - strcpy(init_entry, entryname); + fp = fopen("/etc/init.d/webcit", "w"); + if (fp == NULL) { + display_error("Cannot create /etc/init.d/webcit"); + return; } + + fprintf(fp, "#!/bin/sh\n" + "\n" + "DAEMON=%s/ctdlsvc\n", setup_directory); + fprintf(fp, "\n" + "test -x $DAEMON || exit 0\n" + "test -d /var/run || exit 0\n" + "\n" + "case \"$1\" in\n" + "\n" + "start) echo -n \"Starting WebCit... \"\n" + " if $DAEMON /var/run/webcit.pid %s/webserver " + "-p%s %s %s\n", + setup_directory, http_port, hostname, portname); + fprintf(fp, " then\n" + " echo \"ok\"\n" + " else\n" + " echo \"failed\"\n" + " fi\n"); + fprintf(fp, " ;;\n" + "stop) echo -n \"Stopping WebCit... \"\n" + " kill `cat /var/run/webcit.pid`\n" + " rm -f /var/run/webcit.pid\n" + " echo \"ok\"\n" + " ;;\n" + "*) echo \"Usage: $0 {start|stop}\"\n" + " exit 1\n" + " ;;\n" + "esac\n" + ); + + fclose(fp); + chmod("/etc/init.d/webcit", 0755); } @@ -618,15 +602,6 @@ int main(int argc, char *argv[]) cleanup(0); } - /* If we're on something BSDish then we don't have inittab */ - if (access("/etc/inittab", F_OK)) { - important_message("Not running SysV style init", - "WebCit Setup can only run on systems that use /etc/inittab.\n" - "Please manually configure your startup scripts to run WebCit\n" - "when the system is booted.\n"); - cleanup(0); - } - /* Get started in a valid setup directory. */ strcpy(setup_directory, PREFIX); if ( (using_web_installer) && (getenv("WEBCIT") != NULL) ) { @@ -642,12 +617,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) { @@ -659,24 +635,29 @@ 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); - } - 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); + for (a=0; a<=3; ++a) { + progress("FIXME Starting the WebCit service...", a, 3); + /* if (a == 0) start_the_service(); */ + sleep(1); } - else { + + 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."); - } + } */ cleanup(0); return 0; -- 2.30.2