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
= open(fname
,O_RDWR
);
56 DEBUG(2,("Couldn't open lock file %s (%s)\n",fname
,strerror(errno
)));
60 if (fcntl_lock(fd
,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
,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
,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 (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
,F_SETLKW
,0,1,F_UNLCK
)==False
) {
95 DEBUG(0,("ERROR: can't release lock on %s\n", fname
));
101 if (fcntl_lock(fd
,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
= 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;
195 crec
.cnum
= conn
->cnum
;
196 crec
.uid
= conn
->uid
;
197 crec
.gid
= conn
->gid
;
199 lp_servicename(SNUM(conn
)),sizeof(crec
.name
)-1);
203 crec
.start
= time(NULL
);
205 StrnCpy(crec
.machine
,remote_machine
,sizeof(crec
.machine
)-1);
206 StrnCpy(crec
.addr
,client_addr(Client
),sizeof(crec
.addr
)-1);
209 if (lseek(fd
,foundi
*sizeof(crec
),SEEK_SET
) != foundi
*sizeof(crec
) ||
210 write(fd
, &crec
,sizeof(crec
)) != sizeof(crec
)) {
211 if (fcntl_lock(fd
,F_SETLKW
,0,1,F_UNLCK
)==False
) {
212 DEBUG(0,("ERROR: can't release lock on %s\n", fname
));
218 if (fcntl_lock(fd
,F_SETLKW
,0,1,F_UNLCK
)==False
) {
219 DEBUG(0,("ERROR: can't release lock on %s\n", fname
));