*/
#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;
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;
}
poptFreeContext(pc);
- events = event_context_init();
-
- load_case_tables();
-
if (interactive) {
Fork = False;
log_stdout = True;
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"));
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);
}