r5102: This is a major simplification of the logic for controlling top level
[tprouty/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 "version.h"
28 #include "dynconfig.h"
29 #include "lib/cmdline/popt_common.h"
30 #include "system/dir.h"
31
32
33 /*
34   cleanup temporary files. This is the new alternative to
35   TDB_CLEAR_IF_FIRST. Unfortunately TDB_CLEAR_IF_FIRST is not
36   efficient on unix systems due to the lack of scaling of the byte
37   range locking system. So instead of putting the burden on tdb to
38   cleanup tmp files, this function deletes them. 
39 */
40 static void cleanup_tmp_files(void)
41 {
42         char *path;
43         DIR *dir;
44         struct dirent *de;
45         TALLOC_CTX *mem_ctx = talloc_new(NULL);
46
47         path = smbd_tmp_path(mem_ctx, NULL);
48
49         dir = opendir(path);
50         if (!dir) {
51                 talloc_free(mem_ctx);
52                 return;
53         }
54
55         for (de=readdir(dir);de;de=readdir(dir)) {
56                 char *fname = talloc_asprintf(mem_ctx, "%s/%s", path, de->d_name);
57                 int ret = unlink(fname);
58                 if (ret == -1 &&
59                     errno != ENOENT &&
60                     errno != EISDIR &&
61                     errno != EISDIR) {
62                         DEBUG(0,("Unabled to delete '%s' - %s\n", 
63                                  fname, strerror(errno)));
64                         smb_panic("unable to cleanup tmp files");
65                 }
66                 talloc_free(fname);
67         }
68         closedir(dir);
69
70         talloc_free(mem_ctx);
71 }
72
73 /*
74   setup signal masks
75 */
76 static void setup_signals(void)
77 {
78         fault_setup(NULL);
79         
80         /* we are never interested in SIGPIPE */
81         BlockSignals(True,SIGPIPE);
82
83 #if defined(SIGFPE)
84         /* we are never interested in SIGFPE */
85         BlockSignals(True,SIGFPE);
86 #endif
87
88 #if defined(SIGUSR2)
89         /* We are no longer interested in USR2 */
90         BlockSignals(True,SIGUSR2);
91 #endif
92
93         /* POSIX demands that signals are inherited. If the invoking process has
94          * these signals masked, we will have problems, as we won't recieve them. */
95         BlockSignals(False, SIGHUP);
96         BlockSignals(False, SIGUSR1);
97         BlockSignals(False, SIGTERM);
98 }
99
100
101 /*
102  main server.
103 */
104 static int binary_smbd_main(int argc, const char *argv[])
105 {
106         BOOL interactive = False;
107         int opt;
108         poptContext pc;
109         struct event_context *event_ctx;
110         NTSTATUS status;
111         const char *model = "standard";
112         struct poptOption long_options[] = {
113                 POPT_AUTOHELP
114                 POPT_COMMON_SAMBA
115                 {"interactive", 'i', POPT_ARG_VAL, &interactive, True, 
116                  "Run interactive (not a daemon)", NULL},
117                 {"model", 'M', POPT_ARG_STRING, &model, True, 
118                  "Select process model", "MODEL"},
119                 POPT_COMMON_VERSION
120                 POPT_TABLEEND
121         };
122         
123         pc = poptGetContext("smbd", argc, argv, long_options, 0);
124         
125         while((opt = poptGetNextOpt(pc)) != -1) /* noop */ ;
126
127         poptFreeContext(pc);
128
129         setup_logging(argv[0], interactive?DEBUG_STDOUT:DEBUG_FILE);
130         setup_signals();
131
132         /* we want total control over the permissions on created files,
133            so set our umask to 0 */
134         umask(0);
135
136         reopen_logs();
137
138         DEBUG(0,("smbd version %s started.\n", SAMBA_VERSION_STRING));
139         DEBUGADD(0,("Copyright Andrew Tridgell and the Samba Team 1992-2005\n"));
140
141         if (sizeof(uint16_t) < 2 || sizeof(uint32_t) < 4 || sizeof(uint64_t) < 8) {
142                 DEBUG(0,("ERROR: Samba is not configured correctly for the word size on your machine\n"));
143                 exit(1);
144         }
145
146         lp_load(dyn_CONFIGFILE, False, False, True);
147
148         reopen_logs();
149         load_interfaces();
150
151         if (!interactive) {
152                 DEBUG(3,("Becoming a daemon.\n"));
153                 become_daemon(True);
154         }
155
156         cleanup_tmp_files();
157
158         if (!directory_exist(lp_lockdir(), NULL)) {
159                 mkdir(lp_lockdir(), 0755);
160         }
161
162         pidfile_create("smbd");
163
164         /* Do *not* remove this, until you have removed
165          * passdb/secrets.c, and proved that Samba still builds... */
166         /* Setup the SECRETS subsystem */
167         if (!secrets_init()) {
168                 exit(1);
169         }
170
171         smbd_init_subsystems;
172
173         /* the event context is the top level structure in smbd. Everything else
174            should hang off that */
175         event_ctx = event_context_init(NULL);
176
177         DEBUG(0,("Using %s process model\n", model));
178         status = server_service_startup(event_ctx, model, lp_server_services());
179         if (!NT_STATUS_IS_OK(status)) {
180                 DEBUG(0,("Starting Services failed - %s\n", nt_errstr(status)));
181                 return 1;
182         }
183
184         /* wait for events - this is where smbd sits for most of its
185            life */
186         event_loop_wait(event_ctx);
187
188         /* as everything hangs off this event context, freeing it
189            should initiate a clean shutdown of all services */
190         talloc_free(event_ctx);
191
192         return 0;
193 }
194
195  int main(int argc, const char *argv[])
196 {
197         return binary_smbd_main(argc, argv);
198 }