r4728: split up server_services into:
[jra/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 #include "lib/cmdline/popt_common.h"
26
27 /****************************************************************************
28  main server.
29 ****************************************************************************/
30 static int binary_smbd_main(int argc,const char *argv[])
31 {
32         BOOL is_daemon = False;
33         BOOL interactive = False;
34         BOOL Fork = True;
35         BOOL log_stdout = False;
36         int opt;
37         poptContext pc;
38         struct server_context *server;
39         const char *model = "standard";
40         struct poptOption long_options[] = {
41         POPT_AUTOHELP
42         POPT_COMMON_SAMBA
43         {"daemon", 'D', POPT_ARG_VAL, &is_daemon, True, "Become a daemon (default)" , NULL },
44         {"interactive", 'i', POPT_ARG_VAL, &interactive, True, "Run interactive (not a daemon)", NULL},
45         {"foreground", 'F', POPT_ARG_VAL, &Fork, True, "Run daemon in foreground (for daemontools & etc)" , NULL },
46         {"log-stdout", 'S', POPT_ARG_VAL, &log_stdout, True, "Log to stdout", NULL },
47         {"port", 'p', POPT_ARG_STRING, NULL, 0, "Listen on the specified ports", "PORTS"},
48         {"model", 'M', POPT_ARG_STRING, &model, True, "Select process model", "MODEL"},
49         POPT_COMMON_VERSION
50         POPT_TABLEEND
51         };
52         
53         pc = poptGetContext("smbd", argc, argv, long_options, 0);
54         
55         while((opt = poptGetNextOpt(pc)) != -1) {
56                 switch (opt)  {
57                 case 'p':
58                         lp_set_cmdline("smb ports", poptGetOptArg(pc));
59                         break;
60                 }
61         }
62         poptFreeContext(pc);
63
64         if (interactive) {
65                 Fork = False;
66                 log_stdout = True;
67         }
68
69         if (log_stdout && Fork) {
70                 DEBUG(0,("ERROR: Can't log to stdout (-S) unless daemon is in foreground (-F) or interactive (-i)\n"));
71                 exit(1);
72         }
73         setup_logging(argv[0], log_stdout?DEBUG_STDOUT:DEBUG_FILE);
74
75         fault_setup(NULL);
76         
77         /* we are never interested in SIGPIPE */
78         BlockSignals(True,SIGPIPE);
79
80 #if defined(SIGFPE)
81         /* we are never interested in SIGFPE */
82         BlockSignals(True,SIGFPE);
83 #endif
84
85 #if defined(SIGUSR2)
86         /* We are no longer interested in USR2 */
87         BlockSignals(True,SIGUSR2);
88 #endif
89
90         /* POSIX demands that signals are inherited. If the invoking process has
91          * these signals masked, we will have problems, as we won't recieve them. */
92         BlockSignals(False, SIGHUP);
93         BlockSignals(False, SIGUSR1);
94         BlockSignals(False, SIGTERM);
95
96         /* we want total control over the permissions on created files,
97            so set our umask to 0 */
98         umask(0);
99
100         reopen_logs();
101
102         DEBUG(0,("smbd version %s started.\n", SAMBA_VERSION_STRING));
103         DEBUGADD(0,("Copyright Andrew Tridgell and the Samba Team 1992-2005\n"));
104
105         if (sizeof(uint16_t) < 2 || sizeof(uint32_t) < 4 || sizeof(uint64_t) < 8) {
106                 DEBUG(0,("ERROR: Samba is not configured correctly for the word size on your machine\n"));
107                 exit(1);
108         }
109
110         if (!reload_services(NULL, False))
111                 return(-1);     
112
113         if (!is_daemon && !is_a_socket(0)) {
114                 if (!interactive)
115                         DEBUG(0,("standard input is not a socket, assuming -D option\n"));
116
117                 /*
118                  * Setting is_daemon here prevents us from eventually calling
119                  * the open_sockets_inetd()
120                  */
121
122                 is_daemon = True;
123         }
124
125         if (is_daemon && !interactive) {
126                 DEBUG(3,("Becoming a daemon.\n"));
127                 become_daemon(Fork);
128         }
129
130         if (!directory_exist(lp_lockdir(), NULL)) {
131                 mkdir(lp_lockdir(), 0755);
132         }
133
134         if (is_daemon) {
135                 pidfile_create("smbd");
136         }
137
138         init_subsystems();
139
140         smbd_process_init();
141
142         DEBUG(0,("Using %s process model\n", model));
143         server = server_service_startup(model, lp_server_services());
144         if (!server) {
145                 DEBUG(0,("Starting Services failed.\n"));
146                 return 1;
147         }
148
149         /* wait for events */
150         event_loop_wait(server->event.ctx);
151
152         server_service_shutdown(server, "exit");
153
154         return 0;
155 }
156
157  int main(int argc, const char *argv[])
158 {
159         return binary_smbd_main(argc, argv);
160 }