r10656: BIG merge from trunk. Features not copied over
[Samba/nascimento.git] / source3 / services / svc_rcinit.c
blob5801d076c496ebc22d6b6affedeee68d7b3b53ce
2 /*
3 * Unix SMB/CIFS implementation.
4 * Service Control API Implementation
5 * Copyright (C) Gerald Carter 2005.
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 #include "includes.h"
24 /* Implementation for LSB compliant init scripts */
26 /*******************************************************************************
27 Get the services information by reading and parsing the shell scripts. These
28 are symbolically linked into the SVCCTL_SCRIPT_DIR directory.
30 Get the names of the services/scripts to read from the smb.conf file.
31 *******************************************************************************/
33 BOOL get_LSB_data(char *fname,Service_info *si )
35 pstring initdfile;
36 char mybuffer[256];
37 const char *tokenptr;
38 char **qlines;
39 int fd = -1;
40 int nlines, *numlines,i,in_section,in_description;
42 pstrcpy(si->servicename,"");
43 pstrcpy(si->servicetype,"EXTERNAL");
44 pstrcpy(si->filename,fname);
45 pstrcpy(si->provides,"");
46 pstrcpy(si->dependencies,"");
47 pstrcpy(si->shouldstart,"");
48 pstrcpy(si->shouldstop,"");
49 pstrcpy(si->requiredstart,"");
50 pstrcpy(si->requiredstop,"");
51 pstrcpy(si->description,"");
52 pstrcpy(si->shortdescription,"");
54 numlines = &nlines;
55 in_section = 0;
56 in_description = 0;
59 if( !fname || !*fname ) {
60 DEBUG(0, ("Must define an \"LSB-style init file\" to read.\n"));
61 return False;
63 pstrcpy(initdfile,dyn_LIBDIR);
64 pstrcat(initdfile,SVCCTL_SCRIPT_DIR);
65 pstrcat(initdfile,fname);
67 /* TODO - should check to see if the file that we're trying to open is
68 actually a script. If it's NOT, we should do something like warn,
69 and not continue to try to find info we're looking for */
71 DEBUG(10, ("Opening [%s]\n", initdfile));
72 fd = -1;
73 fd = open(initdfile,O_RDONLY);
74 *numlines = 0;
76 if (fd == -1) {
77 DEBUG(10, ("Couldn't open [%s]\n", initdfile));
78 return False;
81 qlines = fd_lines_load(fd, numlines);
82 DEBUGADD(10, ("Lines returned = [%d]\n", *numlines));
83 close(fd);
86 if (*numlines) {
88 for(i = 0; i < *numlines; i++) {
90 DEBUGADD(10, ("Line[%d] = %s\n", i, qlines[i]));
91 if (!in_section && (0==strwicmp("### BEGIN INIT INFO", qlines[i]))) {
92 /* we now can look for params */
93 DEBUGADD(10, ("Configuration information starts on line = [%d]\n", i));
94 in_section = 1;
96 } else if (in_section && (0==strwicmp("### END INIT INFO", qlines[i]))) {
97 DEBUGADD(10, ("Configuration information ends on line = [%d]\n", i));
98 DEBUGADD(10, ("Description is [%s]\n", si->description));
99 in_description = 0;
100 in_section = 0;
101 break;
102 } else if (in_section) {
103 tokenptr = qlines[i];
104 if (in_description) {
105 DEBUGADD(10, ("Processing DESCRIPTION [%d]\n", *tokenptr));
106 if (tokenptr && (*tokenptr=='#') && (*(tokenptr+1)=='\t')) {
107 DEBUGADD(10, ("Adding to DESCRIPTION [%d]\n", *tokenptr));
108 pstrcat(si->description," ");
109 pstrcat(si->description,tokenptr+2);
110 continue;
112 in_description = 0;
113 DEBUGADD(10, ("Not a description!\n"));
115 if (!next_token(&tokenptr,mybuffer," \t",sizeof(mybuffer))) {
116 DEBUGADD(10, ("Invalid line [%d]\n", i));
117 break; /* bad line? */
119 if (0 != strncmp(mybuffer,"#",1)) {
120 DEBUGADD(10, ("Invalid line [%d], is %s\n", i,mybuffer));
121 break;
123 if (!next_token(&tokenptr,mybuffer," \t",sizeof(mybuffer))) {
124 DEBUGADD(10, ("Invalid token on line [%d]\n", i));
125 break; /* bad line? */
127 DEBUGADD(10, ("Keyword is [%s]\n", mybuffer));
128 if (0==strwicmp(mybuffer,"Description:")) {
129 while (tokenptr && *tokenptr && (strchr(" \t",*tokenptr))) {
130 tokenptr++;
132 pstrcpy(si->description,tokenptr);
133 DEBUGADD(10, ("FOUND DESCRIPTION! Data is [%s]\n", tokenptr));
134 in_description = 1;
135 } else {
136 while (tokenptr && *tokenptr && (strchr(" \t",*tokenptr))) {
137 tokenptr++;
139 DEBUGADD(10, ("Data is [%s]\n", tokenptr));
140 in_description = 0;
142 /* save certain keywords, don't save others */
143 if (0==strwicmp(mybuffer, "Provides:")) {
144 pstrcpy(si->provides,tokenptr);
145 pstrcpy(si->servicename,tokenptr);
148 if (0==strwicmp(mybuffer, "Short-Description:")) {
149 pstrcpy(si->shortdescription,tokenptr);
152 if (0==strwicmp(mybuffer, "Required-start:")) {
153 pstrcpy(si->requiredstart,tokenptr);
154 pstrcpy(si->dependencies,tokenptr);
157 if (0==strwicmp(mybuffer, "Should-start:")) {
158 pstrcpy(si->shouldstart,tokenptr);
164 file_lines_free(qlines);
165 return True;
168 return False;
171 /*********************************************************************
172 *********************************************************************/
174 static WERROR rcinit_stop( const char *service, SERVICE_STATUS *status )
176 pstring command;
177 int ret, fd;
179 pstr_sprintf( command, "%s/%s/%s stop", dyn_LIBDIR, SVCCTL_SCRIPT_DIR, service );
181 /* we've already performed the access check when the service was opened */
183 become_root();
184 ret = smbrun( command , &fd );
185 unbecome_root();
187 DEBUGADD(5, ("rcinit_start: [%s] returned [%d]\n", command, ret));
188 close(fd);
190 ZERO_STRUCTP( status );
191 status->type = 0x0020;
192 status->state = (ret == 0 ) ? 0x0001 : 0x0004;
193 status->controls_accepted = 0x0005;
195 return ( ret == 0 ) ? WERR_OK : WERR_ACCESS_DENIED;
198 /*********************************************************************
199 *********************************************************************/
201 static WERROR rcinit_start( const char *service )
203 pstring command;
204 int ret, fd;
206 pstr_sprintf( command, "%s/%s/%s start", dyn_LIBDIR, SVCCTL_SCRIPT_DIR, service );
208 /* we've already performed the access check when the service was opened */
210 become_root();
211 ret = smbrun( command , &fd );
212 unbecome_root();
214 DEBUGADD(5, ("rcinit_start: [%s] returned [%d]\n", command, ret));
215 close(fd);
217 return ( ret == 0 ) ? WERR_OK : WERR_ACCESS_DENIED;
220 /*********************************************************************
221 *********************************************************************/
223 static WERROR rcinit_status( const char *service, SERVICE_STATUS *status )
225 pstring command;
226 int ret, fd;
228 pstr_sprintf( command, "%s/%s/%s status", dyn_LIBDIR, SVCCTL_SCRIPT_DIR, service );
230 /* we've already performed the access check when the service was opened */
231 /* assume as return code of 0 means that the service is ok. Anything else
232 is STOPPED */
234 become_root();
235 ret = smbrun( command , &fd );
236 unbecome_root();
238 DEBUGADD(5, ("rcinit_start: [%s] returned [%d]\n", command, ret));
239 close(fd);
241 ZERO_STRUCTP( status );
242 status->type = 0x0020;
243 status->state = (ret == 0 ) ? 0x0004 : 0x0001;
244 status->controls_accepted = 0x0005;
246 return WERR_OK;
249 /*********************************************************************
250 *********************************************************************/
252 /* struct for svcctl control to manipulate rcinit service */
254 SERVICE_CONTROL_OPS rcinit_svc_ops = {
255 rcinit_stop,
256 rcinit_start,
257 rcinit_status