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