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