static void *server_routine(void *arg) { static int status = 0; static int started = 0; if (started) { output_error("server routine is already running"); return NULL; } started = 1; sockfd = (SOCKET)arg; // repeat forever.. while (!shutdown_server) { struct sockaddr_in cli_addr; SOCKET newsockfd; int clilen = sizeof(cli_addr); /* accept client request and get client address */ newsockfd = accept(sockfd,(struct sockaddr *)&cli_addr,&clilen); if ((int)newsockfd<0 && errno!=EINTR) { status = GetLastError(); output_error("server accept error on fd=%d: code %d", sockfd, status); goto Done; } else if ((int)newsockfd > 0) { #ifdef WIN32 output_verbose("accepting incoming connection from %d.%d.%d.%d on port %d", cli_addr.sin_addr.S_un.S_un_b.s_b1,cli_addr.sin_addr.S_un.S_un_b.s_b2,cli_addr.sin_addr.S_un.S_un_b.s_b3,cli_addr.sin_addr.S_un.S_un_b.s_b4,cli_addr.sin_port); #else output_verbose("accepting incoming connection from on port %d",cli_addr.sin_port); #endif if ( pthread_create(&thread_id,NULL, http_response,(void*)newsockfd)!=0 ) output_error("unable to start http response thread"); if (global_server_quit_on_close) shutdown_now(); else gui_wait_status(0); } #ifdef NEVER { handleRequest(newsockfd); #ifdef WIN32 closesocket(newsockfd); #else close(newsockfd); #endif } #endif } output_verbose("server shutdown"); Done: started = 0; return (void*)&status; }
/** Process an incoming action request @returns non-zero on success, 0 on failure (errno set) **/ int http_action_request(HTTP *http,char *action) { if (gui_post_action(action)==-1) { http_status(http,HTTP_ACCEPTED); http_type(http,"text/plain"); http_format(http,"Goodbye"); http_send(http); http_close(http); shutdown_now(); return 1; } else return 0; }
/** * timer_callback: * @message: message to display. * * This callback is run every minute until we are ready to shutdown, it * ensures regular warnings are sent to logged in users and handles * preventing new logins. Once time is up, it handles shutting down. * * This will modify delay each time it is called. **/ static void timer_callback (const char *message) { nih_local char *msg = NULL; int warn = FALSE; delay--; msg = NIH_MUST (warning_message (message)); /* Write /etc/nologin with less than 5 minutes remaining */ if (delay <= 5) { FILE *nologin; nologin = fopen (ETC_NOLOGIN, "w"); if (nologin) { fputs (msg, nologin); fclose (nologin); } } /* Only warn at particular intervals */ if (delay < 10) { warn = TRUE; } else if (delay < 60) { warn = (delay % 15 ? FALSE : TRUE); } else if (delay < 180) { warn = (delay % 30 ? FALSE : TRUE); } else { warn = (delay % 60 ? FALSE : TRUE); } if (warn) wall (msg); /* Shutdown the machine at zero */ if (! delay) shutdown_now (); }
int halt_now(void) { return shutdown_now(RB_HALT_SYSTEM); }
int reboot_now(void) { return shutdown_now(RB_AUTOBOOT); }
int main (int argc, char *argv[]) { char ** args; nih_local char *message = NULL; size_t messagelen; nih_local char *msg = NULL; int arg; pid_t pid = 0; nih_main_init (argv[0]); nih_option_set_usage (_("TIME [MESSAGE]")); nih_option_set_synopsis (_("Bring the system down.")); nih_option_set_help ( _("TIME may have different formats, the most common is simply " "the word 'now' which will bring the system down " "immediately. Other valid formats are +m, where m is the " "number of minutes to wait until shutting down and hh:mm " "which specifies the time on the 24hr clock.\n" "\n" "Logged in users are warned by a message sent to their " "terminal, you may include an optional MESSAGE included " "with this. Messages can be sent without actually " "bringing the system down by using the -k option.\n" "\n" "If TIME is given, the command will remain in the " "foreground until the shutdown occurs. It can be cancelled " "by Control-C, or by another user using the -c option.\n" "\n" "The system is brought down into maintenance (single-user) " "mode by default, you can change this with either the -r or " "-h option which specify a reboot or system halt " "respectively. The -h option can be further modified with " "-H or -P to specify whether to halt the system, or to " "power it off afterwards. The default is left up to the " "shutdown scripts.")); args = nih_option_parser (NULL, argc, argv, options, FALSE); if (! args) exit (1); /* If the runlevel wasn't given explicitly, set it to 1 so we go * down into single-user mode. */ if (! runlevel) { runlevel = '1'; init_halt = NULL; } /* When may be specified with -g, or must be first argument */ if (! (cancel || when || args[0])) { fprintf (stderr, _("%s: time expected\n"), program_name); nih_main_suggest_help (); exit (1); } else if (! (cancel || when)) { when = NIH_MUST (nih_strdup (NULL, args[0])); arg = 1; } else { arg = 0; } /* Parse the time argument */ if (when) { if (! strcmp (when, "now")) { /* "now" means, err, now */ delay = 0; } else if (strchr (when, ':')) { /* Clock time */ long hours, mins; char *endptr; struct tm *tm; time_t now; hours = strtoul (when, &endptr, 10); if ((*endptr != ':') || (hours < 0) || (hours > 23)) { fprintf (stderr, _("%s: illegal hour value\n"), program_name); nih_main_suggest_help (); exit (1); } mins = strtoul (endptr + 1, &endptr, 10); if (*endptr || (mins < 0) || (mins > 59)) { fprintf (stderr, _("%s: illegal minute value\n"), program_name); nih_main_suggest_help (); exit (1); } /* Subtract the current time to get the delay. * Add a whole day if we go negative */ now = time (NULL); tm = localtime (&now); delay = (((hours * 60) + mins) - ((tm->tm_hour * 60) + tm->tm_min)); if (delay < 0) delay += 1440; } else { /* Delay in minutes */ char *endptr; delay = strtoul (when, &endptr, 10); if (*endptr || (delay < 0)) { fprintf (stderr, _("%s: illegal time value\n"), program_name); nih_main_suggest_help (); exit (1); } } nih_free (when); } /* The rest of the arguments are a message. * Really this should be just the next argument, but that's not * how this has been traditionally done *sigh* */ message = NIH_MUST (nih_strdup (NULL, "")); messagelen = 0; for (; args[arg]; arg++) { message = NIH_MUST (nih_realloc ( message, NULL, messagelen + strlen(args[arg]) + 4)); strcat (message, args[arg]); strcat (message, " "); messagelen += strlen (args[arg]) + 1; } /* Terminate with \r\n */ if (messagelen) strcat (message, "\r\n"); /* Check we're root, or setuid root */ setuid (geteuid ()); if (getuid ()) { nih_fatal (_("Need to be root")); exit (1); } /* Look for an existing pid file and deal with the existing * process if there is one. */ pid = nih_main_read_pidfile (); if (pid > 0) { if (cancel) { if (kill (pid, SIGINT) < 0) { nih_error (_("Shutdown is not running")); exit (1); } if (messagelen) wall (message); exit (0); } else if (kill (pid, 0) == 0) { nih_error (_("Another shutdown is already running")); exit (1); } } else if (cancel) { nih_error (_("Cannot find pid of running shutdown")); exit (1); } /* Send an initial message */ msg = NIH_MUST (warning_message (message)); wall (msg); if (warn_only) exit (0); /* Give us a sane environment */ if (chdir ("/") < 0) nih_warn ("%s: %s", _("Unable to change directory"), strerror (errno)); umask (022); /* Shutdown now? */ if (! delay) shutdown_now (); /* Save our pid so we can be interrupted later */ if (nih_main_write_pidfile (getpid ()) < 0) { NihError *err; err = nih_error_get (); nih_warn ("%s: %s: %s", nih_main_get_pidfile(), _("Unable to write pid file"), err->message); nih_free (err); } /* Ignore a whole bunch of signals */ nih_signal_set_ignore (SIGCHLD); nih_signal_set_ignore (SIGHUP); nih_signal_set_ignore (SIGTSTP); nih_signal_set_ignore (SIGTTIN); nih_signal_set_ignore (SIGTTOU); /* Catch the usual quit signals */ nih_signal_set_handler (SIGINT, nih_signal_handler); NIH_MUST (nih_signal_add_handler (NULL, SIGINT, cancel_callback, NULL)); nih_signal_set_handler (SIGQUIT, nih_signal_handler); NIH_MUST (nih_signal_add_handler (NULL, SIGQUIT, cancel_callback, NULL)); nih_signal_set_handler (SIGTERM, nih_signal_handler); NIH_MUST (nih_signal_add_handler (NULL, SIGTERM, cancel_callback, NULL)); /* Call a timer every minute until we shutdown */ NIH_MUST (nih_timer_add_periodic (NULL, 60, (NihTimerCb)timer_callback, message)); /* Hang around */ nih_main_loop (); return 0; }
/** * Main function that will be run by the scheduler. * * @param cls closure * @param args remaining command-line arguments * @param cfgfile name of the configuration file used (for saving, can be NULL!) * @param cfg configuration */ static void run (void *cls, char *const *args, const char *cfgfile, const struct GNUNET_CONFIGURATION_Handle *mycfg) { struct GNUNET_CONFIGURATION_Handle *properties; char *file; end_task = GNUNET_SCHEDULER_add_delayed(GNUNET_TIME_UNIT_FOREVER_REL, &shutdown_task, NULL); cfg = mycfg; GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "sysdaemon starting ... \n"); if (GNUNET_SYSERR ==GNUNET_CONFIGURATION_get_value_filename (mycfg, "sysmon", "CFGFILE", &file)) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Sysmon configuration file not set, exit! \n"); shutdown_now(); ret = 1; return; } properties = GNUNET_CONFIGURATION_create(); if (NULL == properties) { GNUNET_break (0); shutdown_now(); ret = 1; return; } if (GNUNET_SYSERR == GNUNET_CONFIGURATION_load (properties, file)) { GNUNET_break (0); GNUNET_CONFIGURATION_destroy (properties); GNUNET_free (file); ret = 1; shutdown_now(); return; } GNUNET_free (file); GNUNET_CONFIGURATION_iterate_sections (properties, &load_property, properties); GNUNET_CONFIGURATION_destroy (properties); /* Creating statistics */ stats = GNUNET_STATISTICS_create ("sysmon", mycfg); if (NULL == stats) { GNUNET_break (0); shutdown_now(); ret = 1; return; } /* load properties */ if (GNUNET_SYSERR == load_default_properties ()) { GNUNET_break (0); shutdown_now(); ret = 1; return; } /* run properties */ if (GNUNET_SYSERR == run_properties ()) { GNUNET_break (0); shutdown_now(); ret = 1; return; } }