1 /* 2 * Copyright (c) 2014 The DragonFly Project. All rights reserved. 3 * 4 * This code is derived from software contributed to The DragonFly Project 5 * by Matthew Dillon <dillon@backplane.com> 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in 15 * the documentation and/or other materials provided with the 16 * distribution. 17 * 3. Neither the name of The DragonFly Project nor the names of its 18 * contributors may be used to endorse or promote products derived 19 * from this software without specific, prior written permission. 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 22 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 23 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 24 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 25 * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 26 * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING, 27 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 28 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 29 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 30 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 31 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 32 * SUCH DAMAGE. 33 */ 34 35 #include <sys/types.h> 36 #include <sys/param.h> 37 #include <sys/procctl.h> 38 #include <sys/stat.h> 39 #include <sys/file.h> 40 #include <sys/time.h> 41 #include <sys/socket.h> 42 #include <sys/wait.h> 43 #include <sys/un.h> 44 #include <sys/ttycom.h> 45 #include <sys/devfs.h> 46 #include <sys/mount.h> 47 #include <sys/jail.h> 48 #include <stdio.h> 49 #include <stdarg.h> 50 #include <stdlib.h> 51 #include <stddef.h> 52 #include <unistd.h> 53 #include <string.h> 54 #include <signal.h> 55 #include <dirent.h> 56 #include <assert.h> 57 #include <errno.h> 58 #include <ctype.h> 59 #include <pwd.h> 60 #include <grp.h> 61 #include <pthread.h> 62 63 typedef struct SvcCommand { 64 int mountdev : 1; 65 int cmdline : 1; 66 int foreground : 1; 67 int restart_some : 1; 68 int restart_all : 1; 69 int exit_mode : 1; 70 int sync_mode : 1; 71 int tail_mode : 3; 72 int jail_clean : 1; 73 int uid_mode : 1; 74 int gid_mode : 1; 75 int manual_stop : 1; 76 int empty_label : 1; /* label not specified (vs 'all') */ 77 int commanded : 1; /* command by system operator */ 78 int force_remove_files : 1; 79 FILE *fp; /* nominal output */ 80 char *piddir; 81 char *rootdir; 82 char *jaildir; 83 char *logfile; 84 char *proctitle; 85 char *directive; 86 char *label; 87 char **ext_av; 88 int ext_ac; 89 char **orig_av; 90 int orig_ac; 91 int restart_timo; 92 int termkill_timo; 93 int debug; 94 int restart_per; 95 int restart_count; 96 struct passwd pwent; 97 struct group grent; 98 gid_t groups[NGROUPS]; 99 int ngroups; 100 101 pthread_cond_t logcond; /* wait for activity */ 102 char logbuf[8192]; /* must be power of 2 >= 2048 */ 103 int logwindex; 104 int logcount; 105 int logfds[2]; /* logfile pipe descriptors */ 106 int logfd; /* logfile file descriptor */ 107 } command_t; 108 109 typedef enum { 110 RS_STOPPED, /* service died or stopped */ 111 RS_STARTED, /* service running */ 112 RS_STOPPING1, /* fresh pid to stop */ 113 RS_STOPPING2, /* TERM sent */ 114 RS_STOPPING3, /* KILL sent */ 115 } runstate_t; 116 117 #define LOGCHUNK 1024 118 119 extern pthread_mutex_t serial_mtx; 120 121 int process_cmd(command_t *cmd, FILE *fp, int ac, char **av); 122 int execute_cmd(command_t *cmd); 123 void free_cmd(command_t *cmd); 124 125 void sfree(char **strp); 126 void sreplace(char **strp, const char *orig); 127 void sdup(char **strp); 128 void afree(char ***aryp); 129 void adup(char ***aryp); 130 int setup_pid_and_socket(command_t *cmd, int *lfdp, int *pfdp); 131 void remove_pid_and_socket(command_t *cmd, const char *label); 132 133 void remote_execute(command_t *cmd, const char *label); 134 void remote_listener(command_t *cmd, int lfd); 135 int remote_wait(void); 136 137 int execute_init(command_t *cmd); 138 int execute_start(command_t *cmd); 139 int execute_stop(command_t *cmd); 140 int execute_restart(command_t *cmd); 141 int execute_exit(command_t *cmd); 142 int execute_list(command_t *cmd); 143 int execute_status(command_t *cmd); 144 int execute_log(command_t *cmd); 145 int execute_logfile(command_t *cmd); 146 int execute_help(command_t *cmd); 147