2 Unix SMB/Netbios implementation.
4 connection claim routines
5 Copyright (C) Andrew Tridgell 1998
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.
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.
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.
25 extern fstring remote_machine;
27 extern int DEBUGLEVEL;
29 /****************************************************************************
30 simple routines to do connection counting
31 ****************************************************************************/
32 BOOL yield_connection(connection_struct *conn,char *name,int max_connections)
34 struct connect_record crec;
40 DEBUG(3,("Yielding connection to %s\n",name));
42 if (max_connections <= 0)
45 bzero(&crec,sizeof(crec));
47 pstrcpy(fname,lp_lockdir());
48 trim_string(fname,"","/");
52 pstrcat(fname,".LCK");
54 fd = sys_open(fname,O_RDWR,0);
56 DEBUG(2,("Couldn't open lock file %s (%s)\n",fname,strerror(errno)));
60 if (fcntl_lock(fd,SMB_F_SETLKW,0,1,F_WRLCK)==False) {
61 DEBUG(0,("ERROR: can't get lock on %s\n", fname));
65 /* find the right spot */
66 for (i=0;i<max_connections;i++) {
67 if (read(fd, &crec,sizeof(crec)) != sizeof(crec)) {
68 DEBUG(2,("Entry not found in lock file %s\n",fname));
69 if (fcntl_lock(fd,SMB_F_SETLKW,0,1,F_UNLCK)==False) {
70 DEBUG(0,("ERROR: can't release lock on %s\n", fname));
75 if (crec.pid == mypid && crec.cnum == conn->cnum)
79 if (crec.pid != mypid || crec.cnum != conn->cnum) {
80 if (fcntl_lock(fd,SMB_F_SETLKW,0,1,F_UNLCK)==False) {
81 DEBUG(0,("ERROR: can't release lock on %s\n", fname));
84 DEBUG(2,("Entry not found in lock file %s\n",fname));
88 bzero((void *)&crec,sizeof(crec));
91 if (sys_lseek(fd,i*sizeof(crec),SEEK_SET) != i*sizeof(crec) ||
92 write(fd, &crec,sizeof(crec)) != sizeof(crec)) {
93 DEBUG(2,("Couldn't update lock file %s (%s)\n",fname,strerror(errno)));
94 if (fcntl_lock(fd,SMB_F_SETLKW,0,1,F_UNLCK)==False) {
95 DEBUG(0,("ERROR: can't release lock on %s\n", fname));
101 if (fcntl_lock(fd,SMB_F_SETLKW,0,1,F_UNLCK)==False) {
102 DEBUG(0,("ERROR: can't release lock on %s\n", fname));
105 DEBUG(3,("Yield successful\n"));
112 /****************************************************************************
113 simple routines to do connection counting
114 ****************************************************************************/
115 BOOL claim_connection(connection_struct *conn,char *name,int max_connections,BOOL Clear)
118 struct connect_record crec;
124 if (max_connections <= 0)
127 DEBUG(5,("trying claim %s %s %d\n",lp_lockdir(),name,max_connections));
129 pstrcpy(fname,lp_lockdir());
130 trim_string(fname,"","/");
132 if (!directory_exist(fname,NULL))
137 pstrcat(fname,".LCK");
139 if (!file_exist(fname,NULL)) {
140 fd = sys_open(fname,O_RDWR|O_CREAT|O_EXCL, 0644);
144 fd = sys_open(fname,O_RDWR,0);
148 DEBUG(1,("couldn't open lock file %s\n",fname));
152 if (fcntl_lock(fd,SMB_F_SETLKW,0,1,F_WRLCK)==False) {
153 DEBUG(0,("ERROR: can't get lock on %s\n", fname));
157 total_recs = file_size(fname) / sizeof(crec);
159 /* find a free spot */
160 for (i=0;i<max_connections;i++) {
162 sys_lseek(fd,i*sizeof(crec),SEEK_SET) != i*sizeof(crec) ||
163 read(fd,&crec,sizeof(crec)) != sizeof(crec)) {
164 if (foundi < 0) foundi = i;
168 if (Clear && crec.pid && !process_exists(crec.pid)) {
169 if(sys_lseek(fd,i*sizeof(crec),SEEK_SET) != i*sizeof(crec)) {
170 DEBUG(0,("claim_connection: ERROR: sys_lseek failed to seek \
171 to %d\n", i*sizeof(crec) ));
174 bzero((void *)&crec,sizeof(crec));
175 write(fd, &crec,sizeof(crec));
176 if (foundi < 0) foundi = i;
179 if (foundi < 0 && (!crec.pid || !process_exists(crec.pid))) {
186 DEBUG(3,("no free locks in %s\n",fname));
187 if (fcntl_lock(fd,SMB_F_SETLKW,0,1,F_UNLCK)==False) {
188 DEBUG(0,("ERROR: can't release lock on %s\n", fname));
194 /* fill in the crec */
195 bzero((void *)&crec,sizeof(crec));
196 crec.magic = 0x280267;
199 crec.cnum = conn->cnum;
200 crec.uid = conn->uid;
201 crec.gid = conn->gid;
203 lp_servicename(SNUM(conn)),sizeof(crec.name)-1);
207 crec.start = time(NULL);
209 StrnCpy(crec.machine,remote_machine,sizeof(crec.machine)-1);
210 StrnCpy(crec.addr,client_addr(Client),sizeof(crec.addr)-1);
213 if (sys_lseek(fd,foundi*sizeof(crec),SEEK_SET) != foundi*sizeof(crec) ||
214 write(fd, &crec,sizeof(crec)) != sizeof(crec)) {
215 if (fcntl_lock(fd,SMB_F_SETLKW,0,1,F_UNLCK)==False) {
216 DEBUG(0,("ERROR: can't release lock on %s\n", fname));
222 if (fcntl_lock(fd,SMB_F_SETLKW,0,1,F_UNLCK)==False) {
223 DEBUG(0,("ERROR: can't release lock on %s\n", fname));