Branch data Line data Source code
1 : : /*-
2 : : * Copyright (c) 2011-2012 Baptiste Daroussin <bapt@FreeBSD.org>
3 : : * All rights reserved.
4 : : *
5 : : * Redistribution and use in source and binary forms, with or without
6 : : * modification, are permitted provided that the following conditions
7 : : * are met:
8 : : * 1. Redistributions of source code must retain the above copyright
9 : : * notice, this list of conditions and the following disclaimer
10 : : * in this position and unchanged.
11 : : * 2. Redistributions in binary form must reproduce the above copyright
12 : : * notice, this list of conditions and the following disclaimer in the
13 : : * documentation and/or other materials provided with the distribution.
14 : : *
15 : : * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
16 : : * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
17 : : * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
18 : : * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
19 : : * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
20 : : * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21 : : * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
22 : : * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23 : : * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
24 : : * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25 : : */
26 : :
27 : : #include <sys/wait.h>
28 : :
29 : : #include <errno.h>
30 : : #include <fcntl.h>
31 : : #include <spawn.h>
32 : : #include <string.h>
33 : : #include <unistd.h>
34 : :
35 : : #include "pkg.h"
36 : : #include "private/pkg.h"
37 : : #include "private/event.h"
38 : :
39 : : static int rc_stop(const char *);
40 : : static int rc_start(const char *);
41 : :
42 : : extern char **environ;
43 : :
44 : : int
45 : 830 : pkg_start_stop_rc_scripts(struct pkg *pkg, pkg_rc_attr attr)
46 : : {
47 : 830 : struct pkg_file *file = NULL;
48 : : char rc_d_path[PATH_MAX];
49 : : const char *rcfile;
50 : : const char *rc;
51 : 830 : size_t len = 0;
52 : 830 : int ret = 0;
53 : : bool handle_rc;
54 : :
55 : 830 : handle_rc = pkg_object_bool(pkg_config_get("HANDLE_RC_SCRIPTS"));
56 [ + - ]: 830 : if (!handle_rc)
57 : 830 : return (ret);
58 : :
59 : 0 : snprintf(rc_d_path, sizeof(rc_d_path), "%s/etc/rc.d/", pkg->prefix);
60 : 0 : len = strlen(rc_d_path);
61 : :
62 [ # # ]: 0 : while (pkg_files(pkg, &file) == EPKG_OK) {
63 [ # # ]: 0 : if (strncmp(rc_d_path, file->path, len) == 0) {
64 : 0 : rcfile = file->path;
65 : 0 : rcfile += len;
66 : 0 : rc = strrchr(rcfile, '/');
67 : 0 : rc++;
68 [ # # # ]: 0 : switch (attr) {
69 : : case PKG_RC_START:
70 : 0 : ret += rc_start(rcfile);
71 : 0 : break;
72 : : case PKG_RC_STOP:
73 : 0 : ret += rc_stop(rcfile);
74 : 0 : break;
75 : : }
76 : 0 : }
77 : : }
78 : :
79 : 0 : return (ret);
80 : 830 : }
81 : :
82 : : static int
83 : 0 : rc_stop(const char *rc_file)
84 : : {
85 : : int error, pstat;
86 : : pid_t pid;
87 : : posix_spawn_file_actions_t actions;
88 : : const char *argv[4];
89 : :
90 [ # # ]: 0 : if (rc_file == NULL)
91 : 0 : return (0);
92 : :
93 : 0 : argv[0] = "service";
94 : 0 : argv[1] = rc_file;
95 : 0 : argv[2] = "onestatus";
96 : 0 : argv[3] = NULL;
97 : :
98 [ # # # # ]: 0 : if ((error = posix_spawn_file_actions_init(&actions)) != 0 ||
99 : 0 : (error = posix_spawn_file_actions_addopen(&actions,
100 [ # # ]: 0 : STDOUT_FILENO, "/dev/null", O_RDONLY, 0)) != 0 ||
101 : 0 : (error = posix_spawn_file_actions_addopen(&actions,
102 [ # # ]: 0 : STDERR_FILENO, "/dev/null", O_RDONLY, 0)) != 0 ||
103 : 0 : (error = posix_spawn(&pid, "/usr/sbin/service", &actions, NULL,
104 : 0 : __DECONST(char **, argv), environ)) != 0) {
105 : 0 : errno = error;
106 : 0 : pkg_errno("Cannot query service '%s'", rc_file);
107 : 0 : return (-1);
108 : : }
109 : :
110 [ # # ]: 0 : while (waitpid(pid, &pstat, 0) == -1) {
111 [ # # ]: 0 : if (errno != EINTR)
112 : 0 : return (-1);
113 : : }
114 : :
115 [ # # ]: 0 : if (WEXITSTATUS(pstat) != 0)
116 : 0 : return (0);
117 : :
118 : 0 : posix_spawn_file_actions_destroy(&actions);
119 : :
120 : 0 : argv[2] = "stop";
121 : :
122 [ # # # # ]: 0 : if ((error = posix_spawn(&pid, "/usr/sbin/service", NULL, NULL,
123 : 0 : __DECONST(char **, argv), environ)) != 0) {
124 : 0 : errno = error;
125 : 0 : pkg_errno("Cannot stop service '%s'", rc_file);
126 : 0 : return (-1);
127 : : }
128 : :
129 [ # # ]: 0 : while (waitpid(pid, &pstat, 0) == -1) {
130 [ # # ]: 0 : if (errno != EINTR)
131 : 0 : return (-1);
132 : : }
133 : :
134 : 0 : return (WEXITSTATUS(pstat));
135 : 0 : }
136 : :
137 : : static int
138 : 0 : rc_start(const char *rc_file)
139 : : {
140 : : int error, pstat;
141 : : pid_t pid;
142 : : const char *argv[4];
143 : :
144 [ # # ]: 0 : if (rc_file == NULL)
145 : 0 : return (0);
146 : :
147 : 0 : argv[0] = "service";
148 : 0 : argv[1] = rc_file;
149 : 0 : argv[2] = "quietstart";
150 : 0 : argv[3] = NULL;
151 : :
152 [ # # # # ]: 0 : if ((error = posix_spawn(&pid, "/usr/sbin/service", NULL, NULL,
153 : 0 : __DECONST(char **, argv), environ)) != 0) {
154 : 0 : errno = error;
155 : 0 : pkg_errno("Cannot start service '%s'", rc_file);
156 : 0 : return (-1);
157 : : }
158 : :
159 [ # # ]: 0 : while (waitpid(pid, &pstat, 0) == -1) {
160 [ # # ]: 0 : if (errno != EINTR)
161 : 0 : return (-1);
162 : : }
163 : :
164 : 0 : return (WEXITSTATUS(pstat));
165 : 0 : }
166 : :
167 : :
|