r4728: split up server_services into:
[bbaumbach/samba-autobuild/.git] / source4 / smbd / process_single.c
1 /* 
2    Unix SMB/CIFS implementation.
3    process model: process (1 process handles all client connections)
4    Copyright (C) Andrew Tridgell 2003
5    Copyright (C) James J Myers 2003 <myersjj@samba.org>
6    Copyright (C) Stefan (metze) Metzmacher 2004
7    
8    This program is free software; you can redistribute it and/or modify
9    it under the terms of the GNU General Public License as published by
10    the Free Software Foundation; either version 2 of the License, or
11    (at your option) any later version.
12    
13    This program is distributed in the hope that it will be useful,
14    but WITHOUT ANY WARRANTY; without even the implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16    GNU General Public License for more details.
17    
18    You should have received a copy of the GNU General Public License
19    along with this program; if not, write to the Free Software
20    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 */
22
23 #include "includes.h"
24 #include "events.h"
25 #include "dlinklist.h"
26 #include "smb_server/smb_server.h"
27 #include "process_model.h"
28
29
30 /*
31   called when the process model is selected
32 */
33 static void single_model_init(struct server_context *server)
34 {
35 }
36
37 static void single_model_exit(struct server_context *server, const char *reason)
38 {
39         DEBUG(1,("single_exit_server: reason[%s]\n",reason));
40         talloc_free(server);
41         exit(0);
42 }
43
44 /*
45   called when a listening socket becomes readable
46 */
47 static void single_accept_connection(struct event_context *ev, struct fd_event *srv_fde, 
48                                      struct timeval t, uint16_t flags)
49 {
50         NTSTATUS status;
51         struct socket_context *sock;
52         struct server_stream_socket *stream_socket = srv_fde->private;
53         struct server_connection *conn;
54
55         /* accept an incoming connection. */
56         status = socket_accept(stream_socket->socket, &sock);
57         if (!NT_STATUS_IS_OK(status)) {
58                 DEBUG(0,("accept_connection_single: accept: %s\n",
59                          nt_errstr(status)));
60                 return;
61         }
62
63         conn = server_setup_connection(ev, stream_socket, sock, t, socket_get_fd(sock));
64         if (!conn) {
65                 DEBUG(10,("server_setup_connection failed\n"));
66                 return;
67         }
68
69         talloc_steal(conn, sock);
70
71         /* return to event handling */
72         return;
73 }
74
75
76
77 /* called when a SMB connection goes down */
78 static void single_terminate_connection(struct server_connection *conn, const char *reason) 
79 {
80         DEBUG(2,("single_terminate_connection: reason[%s]\n",reason));
81
82         if (conn) {
83                 talloc_free(conn);
84         }
85 }
86
87 /*
88   called to create a new event context for a new task
89 */
90 static void single_create_task(struct server_task *task)
91 {
92         task->task.id   = (uint32_t)task;
93         task->event.ctx = task->service->server->event.ctx;
94
95         /* setup to receive internal messages on this connection */
96         task->messaging.ctx = messaging_init(task, task->task.id, task->event.ctx);
97         if (!task->messaging.ctx) {
98                 server_terminate_task(task, "messaging_init() failed");
99                 return;
100         }
101
102         task->task.ops->task_init(task);
103         return;
104 }
105
106 /*
107   called to exit from a server_task
108 */
109 static void single_terminate_task(struct server_task *task, const char *reason)
110 {
111         DEBUG(1,("single_exit_server: reason[%s]\n",reason));
112         talloc_free(task);
113         return;
114 }
115
116 static const struct model_ops single_ops = {
117         .name                   = "single",
118
119         .model_init             = single_model_init,
120         .model_exit             = single_model_exit,
121
122         .accept_connection      = single_accept_connection,
123         .terminate_connection   = single_terminate_connection,
124
125         .create_task            = single_create_task,
126         .terminate_task         = single_terminate_task
127 };
128
129 /*
130   initialise the single process model, registering ourselves with the process model subsystem
131  */
132 NTSTATUS process_model_single_init(void)
133 {
134         NTSTATUS ret;
135
136         /* register ourselves with the PROCESS_MODEL subsystem. */
137         ret = register_process_model(&single_ops);
138         if (!NT_STATUS_IS_OK(ret)) {
139                 DEBUG(0,("Failed to register process_model 'single'!\n"));
140                 return ret;
141         }
142
143         return ret;
144 }