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