blob: 53256184131f637ab64749fcaf2118eb7843003c [file] [log] [blame] [raw]
WHR1cf465e2015-03-03 16:37:02 +08001/* service - toolbox
2 Copyright 2015 libdll.so
3
4 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
5
6 This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
WHRfe52b3b2015-03-07 20:51:28 +08007*/
WHR1cf465e2015-03-03 16:37:02 +08008
WHR0796f352015-03-10 16:27:09 +08009#ifdef _WIN32
10#ifdef _WIN32_WCE
11#include "service.wce.c"
12#else
13#error "Not implemented"
14#endif
15
16#else
17
WHR1cf465e2015-03-03 16:37:02 +080018#include <unistd.h>
19#include <limits.h>
20#include <string.h>
21#include <stdlib.h>
22#include <stdio.h>
23#include <assert.h>
JohnnySund60b3632015-03-04 17:45:53 +080024#include <getopt.h>
JohnnySunc3aa9b62015-03-05 13:01:16 +080025#include <errno.h>
26#include <sys/stat.h>
27#include <sys/types.h>
28#include <dirent.h>
WHRfe52b3b2015-03-07 20:51:28 +080029#include <sys/wait.h>
WHR1cf465e2015-03-03 16:37:02 +080030
31#define INIT_D_PATH "/etc/init.d/"
32
WHRfe52b3b2015-03-07 20:51:28 +080033static const char *env_names[] = {
WHR1cf465e2015-03-03 16:37:02 +080034 "LANG", "PATH", "TERM"
35};
WHRfe52b3b2015-03-07 20:51:28 +080036
37static const char *ignore_names[] = {
38 "skeleton", "README", "rc", "rcS", "single", "reboot", "bootclean.sh", "halt", "killall", "single", "linuxconf", "kudzu"
39};
40
41static char service_script[PATH_MAX+1] = INIT_D_PATH;
42static size_t name_len;
43static char *env[sizeof env_names / sizeof(char *) + 1];
WHR1cf465e2015-03-03 16:37:02 +080044
45static void print_usage(const char *name) {
46 fprintf(stderr, "Usage: %s <service> [<action>] [<options>]\n", name);
47}
48
WHRfe52b3b2015-03-07 20:51:28 +080049static int get_status(const char *pathname) {
50 pid_t pid = fork();
51 if(pid < 0) return '?';
52 if(pid) {
53 int status;
54 if(waitpid(pid, &status, 0) < 0) return '?';
55 if(WIFSIGNALED(status)) return '?';
56 //fprintf(stderr, "%d\n", WEXITSTATUS(status));
WHRfa45a1e2015-03-08 22:20:36 +080057 int e = WEXITSTATUS(status);
58 if(e == 1) return '?';
59 return e == 0 ? '+' : '-';
WHRfe52b3b2015-03-07 20:51:28 +080060 } else {
61 close(STDOUT_FILENO);
62 close(STDERR_FILENO);
63 execle(pathname, pathname, "status", NULL, env);
WHRfa45a1e2015-03-08 22:20:36 +080064 exit(1);
WHRfe52b3b2015-03-07 20:51:28 +080065 }
66}
JohnnySunc3aa9b62015-03-05 13:01:16 +080067
68static int status_all() {
69 struct dirent *de;
JohnnySun10418772015-03-05 17:47:16 +080070 struct stat s;
JohnnySunc3aa9b62015-03-05 13:01:16 +080071 DIR *d = opendir(INIT_D_PATH);
WHRfe52b3b2015-03-07 20:51:28 +080072 int i;
WHR8d594de2015-03-24 23:35:01 +080073 if(!d) {
74 perror(INIT_D_PATH);
75 return 1;
76 }
WHRfe52b3b2015-03-07 20:51:28 +080077first_loop:
78 while((de = readdir(d))) {
JohnnySunc3aa9b62015-03-05 13:01:16 +080079 if((strcmp(de->d_name, ".") == 0) || (strcmp(de->d_name, "..") == 0)) continue;
WHRfe52b3b2015-03-07 20:51:28 +080080 for(i = 0; i < sizeof ignore_names / sizeof(char *); i++) {
81 if(strcmp(de->d_name, ignore_names[i]) == 0) goto first_loop;
82 }
83 //snprintf(tmp, sizeof(tmp), INIT_D_PATH "%s", de->d_name);
84 //strcpy(service_script, INIT_D_PATH);
85 //strcat(service_script, de->d_name);
JohnnySun10418772015-03-05 17:47:16 +080086
WHRfe52b3b2015-03-07 20:51:28 +080087 name_len = strlen(de->d_name);
88 if(sizeof INIT_D_PATH + name_len > sizeof service_script) {
89 continue;
90 }
91 memcpy(service_script + sizeof INIT_D_PATH - 1, de->d_name, name_len + 1);
92
93 if(stat(service_script, &s) < 0) {
94 fprintf(stderr, "stat %s failed: %s", service_script, strerror(errno));
JohnnySun10418772015-03-05 17:47:16 +080095 return -1;
96 }
WHRfe52b3b2015-03-07 20:51:28 +080097 if(!S_ISDIR(s.st_mode) && (s.st_mode & 0111)) {
98 //if(access(tmp, X_OK) == 0)
99 // fprintf(stdout, "%s\n", de->d_name);
100 printf(" [ %c ] %s\n", get_status(service_script), de->d_name);
JohnnySun10418772015-03-05 17:47:16 +0800101 }
JohnnySunc3aa9b62015-03-05 13:01:16 +0800102 }
103 return 0;
104}
JohnnySunf2af6242015-03-04 23:44:11 +0800105
WHRfe52b3b2015-03-07 20:51:28 +0800106static void init_env() {
107 int i;
108 char **p = env;
109 /* How many options the env_names have. */
110 for(i = 0; i < sizeof env_names / sizeof(char *); i++) {
111 char *e = getenv(env_names[i]);
112 /* Copy HEAD to env[i] */
113 if(e) *p++ = e;
114 }
115 *p = NULL;
116}
117
WHR1cf465e2015-03-03 16:37:02 +0800118int service_main(int argc, char **argv) {
JohnnySund60b3632015-03-04 17:45:53 +0800119 static struct option long_options[] = {
WHRfe52b3b2015-03-07 20:51:28 +0800120 { "help", no_argument, 0, 'h' },
121 { "status-all", no_argument, 0, 0 },
122 { 0, 0, 0, 0 }
JohnnySund60b3632015-03-04 17:45:53 +0800123 };
124 while(1) {
125 int option_index = 0;
JohnnySun62422962015-03-04 18:44:48 +0800126 int c = getopt_long(argc, argv, "h", long_options, &option_index);
WHRfe52b3b2015-03-07 20:51:28 +0800127 if(c == -1) break;
JohnnySund60b3632015-03-04 17:45:53 +0800128 switch(c) {
129 case 'h':
130 print_usage(argv[0]);
131 return -1;
JohnnySun62422962015-03-04 18:44:48 +0800132 case 0:
133 //printf("%s\n", long_options[option_index].name);
JohnnySun2d4e0b82015-03-09 17:01:14 +0800134 if(option_index == 1) {
WHRfe52b3b2015-03-07 20:51:28 +0800135 init_env();
JohnnySunc3aa9b62015-03-05 13:01:16 +0800136 status_all();
JohnnySund60b3632015-03-04 17:45:53 +0800137 return 1;
138 }
JohnnySun62422962015-03-04 18:44:48 +0800139 break;
JohnnySund60b3632015-03-04 17:45:53 +0800140 case '?':
141 return -1;
142 default:
143 print_usage(argv[0]);
144 return 0;
145 }
WHR1cf465e2015-03-03 16:37:02 +0800146 }
JohnnySunf2af6242015-03-04 23:44:11 +0800147 /* Check if no option, Avoid Segmentation fault */
JohnnySunb091a0c2015-03-04 23:40:13 +0800148 if(optind == argc) {
149 print_usage(argv[0]);
150 return 0;
WHRfe52b3b2015-03-07 20:51:28 +0800151 }
152 name_len = strlen(argv[1]);
WHR1cf465e2015-03-03 16:37:02 +0800153 if(sizeof INIT_D_PATH + name_len > sizeof service_script) {
154 fprintf(stderr, "%s: Service name too long\n", argv[0]);
155 return 1;
156 }
157 memcpy(service_script + sizeof INIT_D_PATH - 1, argv[1], name_len + 1);
158 if(access(service_script, X_OK) < 0) {
159 fprintf(stderr, "%s: %s: Unrecognized service\n", argv[0], argv[1]);
160 return 1;
161 }
WHRfe52b3b2015-03-07 20:51:28 +0800162 init_env();
WHR1cf465e2015-03-03 16:37:02 +0800163 //execle(service_script, argv[0], argv[2], NULL, env);
164 //perror(argv[1]);
165 argv++;
166 execve(service_script, argv, env);
167 perror(argv[0]);
168 return 1;
169}
WHR0796f352015-03-10 16:27:09 +0800170
171#endif