moved connection_struct handling code into smbd/conn.c and changed it
[ambi/samba-autobuild/.git] / source3 / smbd / conn.c
1 /* 
2    Unix SMB/Netbios implementation.
3    Version 1.9.
4    Manage connections_struct structures
5    Copyright (C) Andrew Tridgell 1998
6    
7    This program is free software; you can redistribute it and/or modify
8    it under the terms of the GNU General Public License as published by
9    the Free Software Foundation; either version 2 of the License, or
10    (at your option) any later version.
11    
12    This program is distributed in the hope that it will be useful,
13    but WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15    GNU General Public License for more details.
16    
17    You should have received a copy of the GNU General Public License
18    along with this program; if not, write to the Free Software
19    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 */
21
22 #include "includes.h"
23
24 extern int DEBUGLEVEL;
25
26 /* set these to define the limits of the server. NOTE These are on a
27    per-client basis. Thus any one machine can't connect to more than
28    MAX_CONNECTIONS services, but any number of machines may connect at
29    one time. */
30 #define MAX_CONNECTIONS 128
31
32 static connection_struct *Connections;
33
34 /* number of open connections */
35 static struct bitmap *bmap;
36 static int num_open;
37
38 /****************************************************************************
39 init the conn structures
40 ****************************************************************************/
41 void conn_init(void)
42 {
43         bmap = bitmap_allocate(MAX_CONNECTIONS);
44 }
45
46 /****************************************************************************
47 return the number of open connections
48 ****************************************************************************/
49 int conn_num_open(void)
50 {
51         return num_open;
52 }
53
54
55 /****************************************************************************
56 check if a snum is in use
57 ****************************************************************************/
58 BOOL conn_snum_used(int snum)
59 {
60         connection_struct *conn;
61         for (conn=Connections;conn;conn=conn->next) {
62                 if (conn->service == snum) {
63                         return(True);
64                 }
65         }
66         return(False);
67 }
68
69
70 /****************************************************************************
71 find a conn given a cnum
72 ****************************************************************************/
73 connection_struct *conn_find(int cnum)
74 {
75         connection_struct *conn;
76
77         for (conn=Connections;conn;conn=conn->next) {
78                 if (conn->cnum == cnum) return conn;
79         }
80
81         return NULL;
82 }
83
84
85 /****************************************************************************
86   find first available connection slot, starting from a random position.
87 The randomisation stops problems with the server dieing and clients
88 thinking the server is still available.
89 ****************************************************************************/
90 connection_struct *conn_new(void)
91 {
92         connection_struct *conn;
93         int i;
94
95         i = bitmap_find(bmap, 1);
96         
97         if (i == -1) {
98                 DEBUG(1,("ERROR! Out of connection structures\n"));            
99                 return NULL;
100         }
101
102         conn = (connection_struct *)malloc(sizeof(*conn));
103         if (!conn) return NULL;
104
105         memset(conn, 0, sizeof(*conn));
106         conn->cnum = i;
107
108         bitmap_set(bmap, i);
109
110         num_open++;
111
112         string_init(&conn->user,"");
113         string_init(&conn->dirpath,"");
114         string_init(&conn->connectpath,"");
115         string_init(&conn->origpath,"");
116         
117         /* hook into the front of the list */
118         if (!Connections) {
119                 Connections = conn;
120         } else {
121                 Connections->prev = conn;
122                 conn->next = Connections;
123                 Connections = conn;
124         }
125
126         return conn;
127 }
128
129 /****************************************************************************
130 close all conn structures
131 ****************************************************************************/
132 void conn_close_all(void)
133 {
134         connection_struct *conn, *next;
135         for (conn=Connections;conn;conn=next) {
136                 next=conn->next;
137                 close_cnum(conn, (uint16)-1);
138         }
139 }
140
141 /****************************************************************************
142 idle inactive connections
143 ****************************************************************************/
144 BOOL conn_idle_all(time_t t, int deadtime)
145 {
146         BOOL allidle = True;
147         connection_struct *conn, *next;
148
149         for (conn=Connections;conn;conn=next) {
150                 next=conn->next;
151                 /* close dirptrs on connections that are idle */
152                 if ((t-conn->lastused) > DPTR_IDLE_TIMEOUT)
153                         dptr_idlecnum(conn);
154
155                 if (conn->num_files_open > 0 || 
156                     (t-conn->lastused)<deadtime)
157                         allidle = False;
158         }
159
160         return allidle;
161 }
162
163 /****************************************************************************
164 free a conn structure
165 ****************************************************************************/
166 void conn_free(connection_struct *conn)
167 {
168         if (conn == Connections) {
169                 Connections = conn->next;
170                 if (Connections) Connections->prev = NULL;
171         } else {
172                 conn->prev->next = conn->next;
173                 if (conn->next) conn->next->prev = conn->prev;
174         }
175
176         if (conn->ngroups && conn->groups) {
177                 free(conn->groups);
178                 conn->groups = NULL;
179                 conn->ngroups = 0;
180         }
181
182         free_namearray(conn->veto_list);
183         free_namearray(conn->hide_list);
184         free_namearray(conn->veto_oplock_list);
185         
186         string_free(&conn->user);
187         string_free(&conn->dirpath);
188         string_free(&conn->connectpath);
189         string_free(&conn->origpath);
190
191         bitmap_clear(bmap, conn->cnum);
192         num_open--;
193
194         memset(conn, 0, sizeof(*conn));
195         free(conn);
196 }