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 connection_struct Connections[MAX_CONNECTIONS];
26 extern fstring remote_machine;
28 extern int DEBUGLEVEL;
30 /****************************************************************************
31 simple routines to do connection counting
32 ****************************************************************************/
33 BOOL yield_connection(int cnum,char *name,int max_connections)
35 struct connect_record crec;
41 DEBUG(3,("Yielding connection to %d %s\n",cnum,name));
43 if (max_connections <= 0)
46 bzero(&crec,sizeof(crec));
48 pstrcpy(fname,lp_lockdir());
49 trim_string(fname,"","/");
55 fd = open(fname,O_RDWR);
57 DEBUG(2,("Couldn't open lock file %s (%s)\n",fname,strerror(errno)));
61 if (fcntl_lock(fd,F_SETLKW,0,1,F_WRLCK)==False) {
62 DEBUG(0,("ERROR: can't get lock on %s\n", fname));
66 /* find the right spot */
67 for (i=0;i<max_connections;i++) {
68 if (read(fd, &crec,sizeof(crec)) != sizeof(crec)) {
69 DEBUG(2,("Entry not found in lock file %s\n",fname));
70 if (fcntl_lock(fd,F_SETLKW,0,1,F_UNLCK)==False) {
71 DEBUG(0,("ERROR: can't release lock on %s\n", fname));
76 if (crec.pid == mypid && crec.cnum == cnum)
80 if (crec.pid != mypid || crec.cnum != cnum) {
81 if (fcntl_lock(fd,F_SETLKW,0,1,F_UNLCK)==False) {
82 DEBUG(0,("ERROR: can't release lock on %s\n", fname));
85 DEBUG(2,("Entry not found in lock file %s\n",fname));
89 bzero((void *)&crec,sizeof(crec));
92 if (lseek(fd,i*sizeof(crec),SEEK_SET) != i*sizeof(crec) ||
93 write(fd, &crec,sizeof(crec)) != sizeof(crec)) {
94 DEBUG(2,("Couldn't update lock file %s (%s)\n",fname,strerror(errno)));
95 if (fcntl_lock(fd,F_SETLKW,0,1,F_UNLCK)==False) {
96 DEBUG(0,("ERROR: can't release lock on %s\n", fname));
102 if (fcntl_lock(fd,F_SETLKW,0,1,F_UNLCK)==False) {
103 DEBUG(0,("ERROR: can't release lock on %s\n", fname));
106 DEBUG(3,("Yield successful\n"));
113 /****************************************************************************
114 simple routines to do connection counting
115 ****************************************************************************/
116 BOOL claim_connection(int cnum,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 strcat(fname,".LCK");
139 if (!file_exist(fname,NULL)) {
140 fd = open(fname,O_RDWR|O_CREAT|O_EXCL, 0644);
144 fd = open(fname,O_RDWR);
148 DEBUG(1,("couldn't open lock file %s\n",fname));
152 if (fcntl_lock(fd,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 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 lseek(fd,i*sizeof(crec),SEEK_SET);
170 bzero((void *)&crec,sizeof(crec));
171 write(fd, &crec,sizeof(crec));
172 if (foundi < 0) foundi = i;
175 if (foundi < 0 && (!crec.pid || !process_exists(crec.pid))) {
182 DEBUG(3,("no free locks in %s\n",fname));
183 if (fcntl_lock(fd,F_SETLKW,0,1,F_UNLCK)==False) {
184 DEBUG(0,("ERROR: can't release lock on %s\n", fname));
190 /* fill in the crec */
191 bzero((void *)&crec,sizeof(crec));
192 crec.magic = 0x280267;
196 crec.uid = Connections[cnum].uid;
197 crec.gid = Connections[cnum].gid;
198 StrnCpy(crec.name,lp_servicename(SNUM(cnum)),sizeof(crec.name)-1);
200 crec.start = time(NULL);
202 StrnCpy(crec.machine,remote_machine,sizeof(crec.machine)-1);
203 StrnCpy(crec.addr,client_addr(),sizeof(crec.addr)-1);
206 if (lseek(fd,foundi*sizeof(crec),SEEK_SET) != foundi*sizeof(crec) ||
207 write(fd, &crec,sizeof(crec)) != sizeof(crec)) {
208 if (fcntl_lock(fd,F_SETLKW,0,1,F_UNLCK)==False) {
209 DEBUG(0,("ERROR: can't release lock on %s\n", fname));
215 if (fcntl_lock(fd,F_SETLKW,0,1,F_UNLCK)==False) {
216 DEBUG(0,("ERROR: can't release lock on %s\n", fname));