r2937: Make sure all memory is initialized
[tprouty/samba.git] / source4 / smbd / server.c
1 /* 
2    Unix SMB/CIFS implementation.
3    Main SMB server routines
4    Copyright (C) Andrew Tridgell                1992-1998
5    Copyright (C) Martin Pool                    2002
6    Copyright (C) Jelmer Vernooij                2002
7    Copyright (C) James J Myers                  2003 <myersjj@samba.org>
8    
9    This program is free software; you can redistribute it and/or modify
10    it under the terms of the GNU General Public License as published by
11    the Free Software Foundation; either version 2 of the License, or
12    (at your option) any later version.
13    
14    This program is distributed in the hope that it will be useful,
15    but WITHOUT ANY WARRANTY; without even the implied warranty of
16    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17    GNU General Public License for more details.
18    
19    You should have received a copy of the GNU General Public License
20    along with this program; if not, write to the Free Software
21    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 */
23
24 #include "includes.h"
25
26 static void exit_server(const char *reason)
27 {
28         DEBUG(3,("Server exit (%s)\n", (reason ? reason : "")));
29         exit(0);
30 }
31
32 /****************************************************************************
33  main server.
34 ****************************************************************************/
35 static int binary_smbd_main(int argc,const char *argv[])
36 {
37         BOOL is_daemon = False;
38         BOOL interactive = False;
39         BOOL Fork = True;
40         BOOL log_stdout = False;
41         int opt;
42         poptContext pc;
43         struct server_context *srv_ctx;
44         const char *model = "standard";
45         struct poptOption long_options[] = {
46                 POPT_AUTOHELP
47         POPT_COMMON_SAMBA
48         {"daemon", 'D', POPT_ARG_VAL, &is_daemon, True, "Become a daemon (default)" , NULL },
49         {"interactive", 'i', POPT_ARG_VAL, &interactive, True, "Run interactive (not a daemon)", NULL},
50         {"foreground", 'F', POPT_ARG_VAL, &Fork, True, "Run daemon in foreground (for daemontools & etc)" , NULL },
51         {"log-stdout", 'S', POPT_ARG_VAL, &log_stdout, True, "Log to stdout", NULL },
52         {"port", 'p', POPT_ARG_STRING, NULL, 0, "Listen on the specified ports", "PORTS"},
53         {"model", 'M', POPT_ARG_STRING, &model, True, "Select process model", "MODEL"},
54         POPT_TABLEEND
55         };
56         
57         pc = poptGetContext("smbd", argc, argv, long_options, 0);
58         
59         while((opt = poptGetNextOpt(pc)) != -1) {
60                 switch (opt)  {
61                 case 'p':
62                         lp_set_cmdline("smb ports", poptGetOptArg(pc));
63                         break;
64                 }
65         }
66         poptFreeContext(pc);
67
68         if (interactive) {
69                 Fork = False;
70                 log_stdout = True;
71         }
72
73         if (log_stdout && Fork) {
74                 DEBUG(0,("ERROR: Can't log to stdout (-S) unless daemon is in foreground (-F) or interactive (-i)\n"));
75                 exit(1);
76         }
77         setup_logging(argv[0], log_stdout?DEBUG_STDOUT:DEBUG_FILE);
78
79         fault_setup((void (*)(void *))exit_server);
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         /* we want total control over the permissions on created files,
101            so set our umask to 0 */
102         umask(0);
103
104         reopen_logs();
105
106         DEBUG(0,("smbd version %s started.\n", SAMBA_VERSION_STRING));
107         DEBUGADD(0,("Copyright Andrew Tridgell and the Samba Team 1992-2004\n"));
108
109         if (sizeof(uint16_t) < 2 || sizeof(uint32_t) < 4 || sizeof(uint64_t) < 8) {
110                 DEBUG(0,("ERROR: Samba is not configured correctly for the word size on your machine\n"));
111                 exit(1);
112         }
113
114         if (!reload_services(NULL, False))
115                 return(-1);     
116
117         if (!is_daemon && !is_a_socket(0)) {
118                 if (!interactive)
119                         DEBUG(0,("standard input is not a socket, assuming -D option\n"));
120
121                 /*
122                  * Setting is_daemon here prevents us from eventually calling
123                  * the open_sockets_inetd()
124                  */
125
126                 is_daemon = True;
127         }
128
129         if (is_daemon && !interactive) {
130                 DEBUG(3,("Becoming a daemon.\n"));
131                 become_daemon(Fork);
132         }
133
134         if (!directory_exist(lp_lockdir(), NULL)) {
135                 mkdir(lp_lockdir(), 0755);
136         }
137
138         if (is_daemon) {
139                 pidfile_create("smbd");
140         }
141
142         init_subsystems();
143
144         DEBUG(0,("Using %s process model\n", model));
145         srv_ctx = server_service_startup(model);
146         if (!srv_ctx) {
147                 DEBUG(0,("Starting Services failed.\n"));
148                 return 1;
149         }
150
151         /* wait for events */
152         return event_loop_wait(srv_ctx->events);
153 }
154
155  int main(int argc, const char *argv[])
156 {
157         return binary_smbd_main(argc, argv);
158 }