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