Remove use of fstring and pstring in dynconfig.c
[samba-svnmirror.git] / source / smbd / server.c
1 /* 
2    Unix SMB/CIFS implementation.
3
4    Main SMB server routines
5
6    Copyright (C) Andrew Tridgell                1992-2005
7    Copyright (C) Martin Pool                    2002
8    Copyright (C) Jelmer Vernooij                2002
9    Copyright (C) James J Myers                  2003 <myersjj@samba.org>
10    
11    This program is free software; you can redistribute it and/or modify
12    it under the terms of the GNU General Public License as published by
13    the Free Software Foundation; either version 2 of the License, or
14    (at your option) any later version.
15    
16    This program is distributed in the hope that it will be useful,
17    but WITHOUT ANY WARRANTY; without even the implied warranty of
18    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19    GNU General Public License for more details.
20    
21    You should have received a copy of the GNU General Public License
22    along with this program; if not, write to the Free Software
23    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 */
25
26 #include "includes.h"
27 #include "lib/events/events.h"
28 #include "version.h"
29 #include "lib/cmdline/popt_common.h"
30 #include "system/dir.h"
31 #include "system/filesys.h"
32
33
34 /*
35   recursively delete a directory tree
36 */
37 static void recursive_delete(const char *path)
38 {
39         DIR *dir;
40         struct dirent *de;
41
42         dir = opendir(path);
43         if (!dir) {
44                 return;
45         }
46
47         for (de=readdir(dir);de;de=readdir(dir)) {
48                 char *fname;
49                 struct stat st;
50
51                 if (strcmp(de->d_name, ".") == 0 ||
52                     strcmp(de->d_name, "..") == 0) {
53                         continue;
54                 }
55
56                 fname = talloc_asprintf(path, "%s/%s", path, de->d_name);
57                 if (stat(fname, &st) != 0) {
58                         continue;
59                 }
60                 if (S_ISDIR(st.st_mode)) {
61                         recursive_delete(fname);
62                         talloc_free(fname);
63                         continue;
64                 }
65                 if (unlink(fname) != 0) {
66                         DEBUG(0,("Unabled to delete '%s' - %s\n", 
67                                  fname, strerror(errno)));
68                         smb_panic("unable to cleanup tmp files");
69                 }
70                 talloc_free(fname);
71         }
72         closedir(dir);
73 }
74
75 /*
76   cleanup temporary files. This is the new alternative to
77   TDB_CLEAR_IF_FIRST. Unfortunately TDB_CLEAR_IF_FIRST is not
78   efficient on unix systems due to the lack of scaling of the byte
79   range locking system. So instead of putting the burden on tdb to
80   cleanup tmp files, this function deletes them. 
81 */
82 static void cleanup_tmp_files(void)
83 {
84         char *path;
85         TALLOC_CTX *mem_ctx = talloc_new(NULL);
86
87         path = smbd_tmp_path(mem_ctx, NULL);
88
89         recursive_delete(path);
90         talloc_free(mem_ctx);
91 }
92
93 /*
94   setup signal masks
95 */
96 static void setup_signals(void)
97 {
98         /* we are never interested in SIGPIPE */
99         BlockSignals(True,SIGPIPE);
100
101 #if defined(SIGFPE)
102         /* we are never interested in SIGFPE */
103         BlockSignals(True,SIGFPE);
104 #endif
105
106 #if defined(SIGUSR2)
107         /* We are no longer interested in USR2 */
108         BlockSignals(True,SIGUSR2);
109 #endif
110
111         /* POSIX demands that signals are inherited. If the invoking process has
112          * these signals masked, we will have problems, as we won't recieve them. */
113         BlockSignals(False, SIGHUP);
114         BlockSignals(False, SIGUSR1);
115         BlockSignals(False, SIGTERM);
116 }
117
118
119 /*
120   handle io on stdin
121 */
122 static void server_stdin_handler(struct event_context *event_ctx, struct fd_event *fde, 
123                                  uint16_t flags, void *private)
124 {
125         uint8_t c;
126         if (read(0, &c, 1) == 0) {
127                 DEBUG(0,("smbd: EOF on stdin - terminating\n"));
128                 exit(0);
129         }
130 }
131
132
133 /*
134   die if the user selected maximum runtime is exceeded
135 */
136 static void max_runtime_handler(struct event_context *ev, struct timed_event *te, 
137                                 struct timeval t, void *private)
138 {
139         DEBUG(0,("smbd maximum runtime exceeded - terminating\n"));
140         exit(0);
141 }
142
143
144 /*
145  main server.
146 */
147 static int binary_smbd_main(int argc, const char *argv[])
148 {
149         BOOL interactive = False;
150         int opt;
151         poptContext pc;
152         struct event_context *event_ctx;
153         NTSTATUS status;
154         const char *model = "standard";
155         int max_runtime = 0;
156         struct poptOption long_options[] = {
157                 POPT_AUTOHELP
158                 {"interactive", 'i', POPT_ARG_VAL, &interactive, True, 
159                  "Run interactive (not a daemon)", NULL},
160                 {"model", 'M', POPT_ARG_STRING, &model, True, 
161                  "Select process model", "MODEL"},
162                 {"maximum-runtime", 0, POPT_ARG_INT, &max_runtime, True, 
163                  "set maximum time for smbd to live", "seconds"},
164                 POPT_COMMON_SAMBA
165                 POPT_COMMON_VERSION
166                 POPT_TABLEEND
167         };
168         
169         pc = poptGetContext("smbd", argc, argv, long_options, 0);
170         
171         while((opt = poptGetNextOpt(pc)) != -1) /* noop */ ;
172
173         poptFreeContext(pc);
174
175         setup_logging(argv[0], interactive?DEBUG_STDOUT:DEBUG_FILE);
176         setup_signals();
177
178         /* we want total control over the permissions on created files,
179            so set our umask to 0 */
180         umask(0);
181
182         DEBUG(0,("smbd version %s started.\n", SAMBA_VERSION_STRING));
183         DEBUGADD(0,("Copyright Andrew Tridgell and the Samba Team 1992-2005\n"));
184
185         if (sizeof(uint16_t) < 2 || sizeof(uint32_t) < 4 || sizeof(uint64_t) < 8) {
186                 DEBUG(0,("ERROR: Samba is not configured correctly for the word size on your machine\n"));
187                 exit(1);
188         }
189
190         if (!interactive) {
191                 DEBUG(3,("Becoming a daemon.\n"));
192                 become_daemon(True);
193         }
194
195         cleanup_tmp_files();
196
197         if (!directory_exist(lp_lockdir())) {
198                 mkdir(lp_lockdir(), 0755);
199         }
200
201         pidfile_create("smbd");
202
203         /* Do *not* remove this, until you have removed
204          * passdb/secrets.c, and proved that Samba still builds... */
205         /* Setup the SECRETS subsystem */
206         if (!secrets_init()) {
207                 exit(1);
208         }
209
210         smbd_init_subsystems;
211
212         /* the event context is the top level structure in smbd. Everything else
213            should hang off that */
214         event_ctx = event_context_init(NULL);
215
216         if (interactive) {
217                 /* catch EOF on stdin */
218 #ifdef SIGTTIN
219                 signal(SIGTTIN, SIG_IGN);
220 #endif
221                 event_add_fd(event_ctx, event_ctx, 0, EVENT_FD_READ, 
222                              server_stdin_handler, NULL);
223         }
224
225
226         if (max_runtime) {
227                 event_add_timed(event_ctx, event_ctx, 
228                                 timeval_current_ofs(max_runtime, 0), 
229                                 max_runtime_handler, NULL);
230         }
231
232         DEBUG(0,("Using %s process model\n", model));
233         status = server_service_startup(event_ctx, model, lp_server_services());
234         if (!NT_STATUS_IS_OK(status)) {
235                 DEBUG(0,("Starting Services failed - %s\n", nt_errstr(status)));
236                 return 1;
237         }
238
239         /* wait for events - this is where smbd sits for most of its
240            life */
241         event_loop_wait(event_ctx);
242
243         /* as everything hangs off this event context, freeing it
244            should initiate a clean shutdown of all services */
245         talloc_free(event_ctx);
246
247         return 0;
248 }
249
250  int main(int argc, const char *argv[])
251 {
252         return binary_smbd_main(argc, argv);
253 }