3 * Unix SMB/CIFS implementation.
4 * Service Control API Implementation
5 * Copyright (C) Gerald Carter 2005.
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.
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 )
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,"");
59 if( !fname || !*fname ) {
60 DEBUG(0, ("Must define an \"LSB-style init file\" to read.\n"));
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));
73 fd = open(initdfile,O_RDONLY);
77 DEBUG(10, ("Couldn't open [%s]\n", initdfile));
81 qlines = fd_lines_load(fd, numlines);
82 DEBUGADD(10, ("Lines returned = [%d]\n", *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));
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));
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);
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));
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))) {
132 pstrcpy(si->description,tokenptr);
133 DEBUGADD(10, ("FOUND DESCRIPTION! Data is [%s]\n", tokenptr));
136 while (tokenptr && *tokenptr && (strchr(" \t",*tokenptr))) {
139 DEBUGADD(10, ("Data is [%s]\n", tokenptr));
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);
171 /*********************************************************************
172 *********************************************************************/
174 static WERROR rcinit_stop( const char *service, SERVICE_STATUS *status )
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 */
184 ret = smbrun( command , &fd );
187 DEBUGADD(5, ("rcinit_start: [%s] returned [%d]\n", command, ret));
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 )
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 */
211 ret = smbrun( command , &fd );
214 DEBUGADD(5, ("rcinit_start: [%s] returned [%d]\n", command, ret));
217 return ( ret == 0 ) ? WERR_OK : WERR_ACCESS_DENIED;
220 /*********************************************************************
221 *********************************************************************/
223 static WERROR rcinit_status( const char *service, SERVICE_STATUS *status )
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
235 ret = smbrun( command , &fd );
238 DEBUGADD(5, ("rcinit_start: [%s] returned [%d]\n", command, ret));
241 ZERO_STRUCTP( status );
242 status->type = 0x0020;
243 status->state = (ret == 0 ) ? 0x0004 : 0x0001;
244 status->controls_accepted = 0x0005;
249 /*********************************************************************
250 *********************************************************************/
252 /* struct for svcctl control to manipulate rcinit service */
254 SERVICE_CONTROL_OPS rcinit_svc_ops = {