r4322: use a nicer name
[samba.git] / source4 / smbd / server.c
index 1dc8082b309c3b0f5a8b237f8cb8df3615e1f7cf..830d26fa7f99357f957fb20893ec5fd89e63bcf4 100644 (file)
 */
 
 #include "includes.h"
+#include "lib/cmdline/popt_common.h"
 
-
-/*
-  called on a fatal error that should cause this server to terminate
-*/
-void exit_server(struct server_context *smb, const char *reason)
-{
-       smb->model_ops->terminate_connection(smb, reason);
-}
-
-
-/*
-  setup a single listener of any type
- */
-static void setup_listen(struct event_context *events,
-                        const struct model_ops *model_ops, 
-                        void (*accept_handler)(struct event_context *,struct fd_event *,time_t,uint16_t),
-                        struct in_addr *ifip, unsigned port)
-{
-       struct fd_event fde;
-       fde.fd = open_socket_in(SOCK_STREAM, port, 0, ifip->s_addr, True);
-       if (fde.fd == -1) {
-               DEBUG(0,("Failed to open socket on %s:%u - %s\n",
-                        inet_ntoa(*ifip), port, strerror(errno)));
-               return;
-       }
-
-       /* ready to listen */
-       set_socket_options(fde.fd, "SO_KEEPALIVE"); 
-       set_socket_options(fde.fd, lp_socket_options());
-      
-       if (listen(fde.fd, SMBD_LISTEN_BACKLOG) == -1) {
-               DEBUG(0,("Failed to listen on %s:%d - %s\n",
-                        inet_ntoa(*ifip), port, strerror(errno)));
-               close(fde.fd);
-               return;
-       }
-
-       /* we are only interested in read events on the listen socket */
-       fde.flags = EVENT_FD_READ;
-       fde.private = model_ops;
-       fde.handler = accept_handler;
-       
-       event_add_fd(events, &fde);
-}
-
-/*
-  add a socket address to the list of events, one event per port
-*/
-static void add_socket(struct event_context *events, 
-                      const struct model_ops *model_ops, 
-                      struct in_addr *ifip)
-{
-       char *ptr, *tok;
-       const char *delim = ", ";
-
-       for (tok=strtok_r(lp_smb_ports(), delim, &ptr); 
-            tok; 
-            tok=strtok_r(NULL, delim, &ptr)) {
-               unsigned port = atoi(tok);
-               if (port == 0) continue;
-               setup_listen(events, model_ops, model_ops->accept_connection, ifip, port);
-       }
-}
-
-/****************************************************************************
- Open the socket communication.
-****************************************************************************/
-static void open_sockets_smbd(struct event_context *events,
-                             const struct model_ops *model_ops)
-{
-       if (lp_interfaces() && lp_bind_interfaces_only()) {
-               int num_interfaces = iface_count();
-               int i;
-
-               /* We have been given an interfaces line, and been 
-                  told to only bind to those interfaces. Create a
-                  socket per interface and bind to only these.
-               */
-               for(i = 0; i < num_interfaces; i++) {
-                       struct in_addr *ifip = iface_n_ip(i);
-
-                       if (ifip == NULL) {
-                               DEBUG(0,("open_sockets_smbd: interface %d has NULL IP address !\n", i));
-                               continue;
-                       }
-
-                       add_socket(events, model_ops, ifip);
-               }
-       } else {
-               TALLOC_CTX *mem_ctx = talloc_init("open_sockets_smbd");
-               
-               struct in_addr *ifip = interpret_addr2(mem_ctx, lp_socket_address());
-               /* Just bind to lp_socket_address() (usually 0.0.0.0) */
-               if (!mem_ctx) {
-                       smb_panic("No memory");
-               }
-               add_socket(events, model_ops, ifip);
-               talloc_destroy(mem_ctx);
-       } 
-}
-
-/****************************************************************************
- Reload the services file.
-**************************************************************************/
-BOOL reload_services(struct server_context *smb, BOOL test)
-{
-       BOOL ret;
-       
-       if (lp_loaded()) {
-               pstring fname;
-               pstrcpy(fname,lp_configfile());
-               if (file_exist(fname, NULL) &&
-                   !strcsequal(fname, dyn_CONFIGFILE)) {
-                       pstrcpy(dyn_CONFIGFILE, fname);
-                       test = False;
-               }
-       }
-
-       reopen_logs();
-
-       if (test && !lp_file_list_changed())
-               return(True);
-
-       if (smb) {
-               lp_killunused(smb, conn_snum_used);
-       }
-       
-       ret = lp_load(dyn_CONFIGFILE, False, False, True);
-
-       load_printers();
-
-       /* perhaps the config filename is now set */
-       if (!test)
-               reload_services(smb, True);
-
-       reopen_logs();
-
-       load_interfaces();
-
-       mangle_reset_cache();
-       reset_stat_cache();
-
-       /* this forces service parameters to be flushed */
-       set_current_service(NULL,True);
-
-       return(ret);
-}
-
-/****************************************************************************
- Initialise connect, service and file structs.
-****************************************************************************/
-static BOOL init_structs(void)
+static void exit_server(const char *reason)
 {
-       init_names();
-       file_init();
-       secrets_init();
-
-       /* we want to re-seed early to prevent time delays causing
-           client problems at a later date. (tridge) */
-       generate_random_buffer(NULL, 0, False);
-
-       return True;
-}
-
-
-/*
-  setup the events for the chosen process model
-*/
-static void setup_process_model(struct event_context *events, 
-                               const char *model)
-{
-       const struct model_ops *ops;
-
-       ops = process_model_byname(model);
-       if (!ops) {
-               DEBUG(0,("Unknown process model '%s'\n", model));
-               exit(-1);
-       }
-
-       ops->model_startup();
-
-       /* now setup the listening sockets, adding 
-          event handlers to the events structure */
-       open_sockets_smbd(events, ops);
-
-       /* setup any sockets we need to listen on for RPC over TCP */
-       open_sockets_rpc(events, ops);
+       DEBUG(3,("Server exit (%s)\n", (reason ? reason : "")));
+       exit(0);
 }
 
 /****************************************************************************
- main program.
+ main server.
 ****************************************************************************/
- int main(int argc,const char *argv[])
+static int binary_smbd_main(int argc,const char *argv[])
 {
        BOOL is_daemon = False;
        BOOL interactive = False;
@@ -223,30 +41,24 @@ static void setup_process_model(struct event_context *events,
        BOOL log_stdout = False;
        int opt;
        poptContext pc;
-       struct event_context *events;
+       struct server_context *srv_ctx;
        const char *model = "standard";
        struct poptOption long_options[] = {
                POPT_AUTOHELP
-       {"daemon", 'D', POPT_ARG_VAL, &is_daemon, True, "Become a daemon (default)" },
-       {"interactive", 'i', POPT_ARG_VAL, &interactive, True, "Run interactive (not a daemon)"},
-       {"foreground", 'F', POPT_ARG_VAL, &Fork, False, "Run daemon in foreground (for daemontools & etc)" },
-       {"log-stdout", 'S', POPT_ARG_VAL, &log_stdout, True, "Log to stdout" },
-       {"build-options", 'b', POPT_ARG_NONE, NULL, 'b', "Print build options" },
-       {"port", 'p', POPT_ARG_STRING, NULL, 0, "Listen on the specified ports"},
-       {"model", 'M', POPT_ARG_STRING, &model, 0, "select process model"},
        POPT_COMMON_SAMBA
-       { NULL }
+       {"daemon", 'D', POPT_ARG_VAL, &is_daemon, True, "Become a daemon (default)" , NULL },
+       {"interactive", 'i', POPT_ARG_VAL, &interactive, True, "Run interactive (not a daemon)", NULL},
+       {"foreground", 'F', POPT_ARG_VAL, &Fork, True, "Run daemon in foreground (for daemontools & etc)" , NULL },
+       {"log-stdout", 'S', POPT_ARG_VAL, &log_stdout, True, "Log to stdout", NULL },
+       {"port", 'p', POPT_ARG_STRING, NULL, 0, "Listen on the specified ports", "PORTS"},
+       {"model", 'M', POPT_ARG_STRING, &model, True, "Select process model", "MODEL"},
+       POPT_TABLEEND
        };
        
        pc = poptGetContext("smbd", argc, argv, long_options, 0);
        
        while((opt = poptGetNextOpt(pc)) != -1) {
                switch (opt)  {
-               case 'b':
-                       /* Display output to screen as well as debug */
-                       build_options(True); 
-                       exit(0);
-                       break;
                case 'p':
                        lp_set_cmdline("smb ports", poptGetOptArg(pc));
                        break;
@@ -254,10 +66,6 @@ static void setup_process_model(struct event_context *events,
        }
        poptFreeContext(pc);
 
-       events = event_context_init();
-
-       load_case_tables();
-
        if (interactive) {
                Fork = False;
                log_stdout = True;
@@ -299,20 +107,14 @@ static void setup_process_model(struct event_context *events,
        DEBUG(0,("smbd version %s started.\n", SAMBA_VERSION_STRING));
        DEBUGADD(0,("Copyright Andrew Tridgell and the Samba Team 1992-2004\n"));
 
-       /* Output the build options to the debug log */ 
-       build_options(False);
-
-       if (sizeof(uint16_t) < 2 || sizeof(uint32_t) < 4) {
+       if (sizeof(uint16_t) < 2 || sizeof(uint32_t) < 4 || sizeof(uint64_t) < 8) {
                DEBUG(0,("ERROR: Samba is not configured correctly for the word size on your machine\n"));
                exit(1);
        }
-       DEBUG(0,("Using %s process model\n", model));
-                       
+
        if (!reload_services(NULL, False))
                return(-1);     
 
-       init_structs();
-
        if (!is_daemon && !is_a_socket(0)) {
                if (!interactive)
                        DEBUG(0,("standard input is not a socket, assuming -D option\n"));
@@ -338,13 +140,20 @@ static void setup_process_model(struct event_context *events,
                pidfile_create("smbd");
        }
 
-       register_msg_pool_usage();
-       register_dmalloc_msgs();
-
        init_subsystems();
 
-       setup_process_model(events, model);
+       DEBUG(0,("Using %s process model\n", model));
+       srv_ctx = server_service_startup(model);
+       if (!srv_ctx) {
+               DEBUG(0,("Starting Services failed.\n"));
+               return 1;
+       }
 
        /* wait for events */
-       return event_loop_wait(events);
+       return event_loop_wait(srv_ctx->events);
+}
+
+ int main(int argc, const char *argv[])
+{
+       return binary_smbd_main(argc, argv);
 }