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
= {