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 : 201 : pkg_start_stop_rc_scripts(struct pkg *pkg, pkg_rc_attr attr)
46 : : {
47 : 201 : struct pkg_file *file = NULL;
48 : : char rc_d_path[PATH_MAX];
49 : : const char *rcfile;
50 : 201 : size_t len = 0;
51 : 201 : int ret = 0;
52 : : bool handle_rc;
53 : :
54 : 201 : handle_rc = pkg_object_bool(pkg_config_get("HANDLE_RC_SCRIPTS"));
55 [ - + ]: 201 : if (!handle_rc)
56 : 201 : return (ret);
57 : :
58 : 0 : snprintf(rc_d_path, sizeof(rc_d_path), "%s/etc/rc.d/", pkg->prefix);
59 : 0 : len = strlen(rc_d_path);
60 : :
61 [ # # ]: 0 : while (pkg_files(pkg, &file) == EPKG_OK) {
62 [ # # ]: 0 : if (strncmp(rc_d_path, file->path, len) == 0) {
63 : 0 : rcfile = file->path;
64 : 0 : rcfile += len;
65 [ # # # ]: 0 : switch (attr) {
66 : : case PKG_RC_START:
67 : 0 : ret += rc_start(rcfile);
68 : 0 : break;
69 : : case PKG_RC_STOP:
70 : 0 : ret += rc_stop(rcfile);
71 : 0 : break;
72 : : }
73 : 0 : }
74 : : }
75 : :
76 : 0 : return (ret);
77 : 201 : }
78 : :
79 : : static int
80 : 0 : rc_stop(const char *rc_file)
81 : : {
82 : : int error, pstat;
83 : : pid_t pid;
84 : : posix_spawn_file_actions_t actions;
85 : : const char *argv[4];
86 : :
87 [ # # ]: 0 : if (rc_file == NULL)
88 : 0 : return (0);
89 : :
90 : 0 : argv[0] = "service";
91 : 0 : argv[1] = rc_file;
92 : 0 : argv[2] = "onestatus";
93 : 0 : argv[3] = NULL;
94 : :
95 [ # # # # ]: 0 : if ((error = posix_spawn_file_actions_init(&actions)) != 0 ||
96 : 0 : (error = posix_spawn_file_actions_addopen(&actions,
97 [ # # ]: 0 : STDOUT_FILENO, "/dev/null", O_RDONLY, 0)) != 0 ||
98 : 0 : (error = posix_spawn_file_actions_addopen(&actions,
99 [ # # ]: 0 : STDERR_FILENO, "/dev/null", O_RDONLY, 0)) != 0 ||
100 : 0 : (error = posix_spawn(&pid, "/usr/sbin/service", &actions, NULL,
101 : 0 : __DECONST(char **, argv), environ)) != 0) {
102 : 0 : errno = error;
103 : 0 : pkg_errno("Cannot query service '%s'", rc_file);
104 : 0 : return (-1);
105 : : }
106 : :
107 [ # # ]: 0 : while (waitpid(pid, &pstat, 0) == -1) {
108 [ # # ]: 0 : if (errno != EINTR)
109 : 0 : return (-1);
110 : : }
111 : :
112 [ # # ]: 0 : if (WEXITSTATUS(pstat) != 0)
113 : 0 : return (0);
114 : :
115 : 0 : posix_spawn_file_actions_destroy(&actions);
116 : :
117 : 0 : argv[2] = "stop";
118 : :
119 [ # # # # ]: 0 : if ((error = posix_spawn(&pid, "/usr/sbin/service", NULL, NULL,
120 : 0 : __DECONST(char **, argv), environ)) != 0) {
121 : 0 : errno = error;
122 : 0 : pkg_errno("Cannot stop service '%s'", rc_file);
123 : 0 : return (-1);
124 : : }
125 : :
126 [ # # ]: 0 : while (waitpid(pid, &pstat, 0) == -1) {
127 [ # # ]: 0 : if (errno != EINTR)
128 : 0 : return (-1);
129 : : }
130 : :
131 : 0 : return (WEXITSTATUS(pstat));
132 : 0 : }
133 : :
134 : : static int
135 : 0 : rc_start(const char *rc_file)
136 : : {
137 : : int error, pstat;
138 : : pid_t pid;
139 : : const char *argv[4];
140 : :
141 [ # # ]: 0 : if (rc_file == NULL)
142 : 0 : return (0);
143 : :
144 : 0 : argv[0] = "service";
145 : 0 : argv[1] = rc_file;
146 : 0 : argv[2] = "quietstart";
147 : 0 : argv[3] = NULL;
148 : :
149 [ # # # # ]: 0 : if ((error = posix_spawn(&pid, "/usr/sbin/service", NULL, NULL,
150 : 0 : __DECONST(char **, argv), environ)) != 0) {
151 : 0 : errno = error;
152 : 0 : pkg_errno("Cannot start service '%s'", rc_file);
153 : 0 : return (-1);
154 : : }
155 : :
156 [ # # ]: 0 : while (waitpid(pid, &pstat, 0) == -1) {
157 [ # # ]: 0 : if (errno != EINTR)
158 : 0 : return (-1);
159 : : }
160 : :
161 : 0 : return (WEXITSTATUS(pstat));
162 : 0 : }
163 : :
164 : :
|