r5632: Fix infinite looping bug found by nasty BlueArc test :-).
[Samba.git] / source / smbwrapper / shared.c
blobca8df5841d1e3b9a18e7e8792277aa0e66a4abf4
1 /*
2 Unix SMB/CIFS implementation.
3 SMB wrapper functions - shared variables
4 Copyright (C) Andrew Tridgell 1998
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 #include "includes.h"
23 static int shared_fd;
24 static char *variables;
25 static int shared_size;
27 /*****************************************************
28 setup the shared area
29 *******************************************************/
30 void smbw_setup_shared(void)
32 int fd;
33 pstring name, s;
35 slprintf(name,sizeof(name)-1, "%s/smbw.XXXXXX",tmpdir());
37 fd = smb_mkstemp(name);
39 if (fd == -1) goto failed;
41 unlink(name);
43 shared_fd = set_maxfiles(SMBW_MAX_OPEN);
45 while (shared_fd && dup2(fd, shared_fd) != shared_fd) shared_fd--;
47 if (shared_fd == 0) goto failed;
49 close(fd);
51 DEBUG(4,("created shared_fd=%d\n", shared_fd));
53 slprintf(s,sizeof(s)-1,"%d", shared_fd);
55 setenv("SMBW_HANDLE", s, 1);
57 return;
59 failed:
60 perror("Failed to setup shared variable area ");
61 exit(1);
64 static int locked;
66 /*****************************************************
67 lock the shared variable area
68 *******************************************************/
69 static void lockit(void)
71 if (shared_fd == 0) {
72 char *p = getenv("SMBW_HANDLE");
73 if (!p) {
74 DEBUG(0,("ERROR: can't get smbw shared handle\n"));
75 exit(1);
77 shared_fd = atoi(p);
79 if (locked==0 &&
80 fcntl_lock(shared_fd,SMB_F_SETLKW,0,1,F_WRLCK)==False) {
81 DEBUG(0,("ERROR: can't get smbw shared lock (%s)\n", strerror(errno)));
82 exit(1);
84 locked++;
87 /*****************************************************
88 unlock the shared variable area
89 *******************************************************/
90 static void unlockit(void)
92 locked--;
93 if (locked == 0) {
94 fcntl_lock(shared_fd,SMB_F_SETLK,0,1,F_UNLCK);
99 /*****************************************************
100 get a variable from the shared area
101 *******************************************************/
102 char *smbw_getshared(const char *name)
104 int i;
105 struct stat st;
106 char *var;
108 lockit();
110 /* maybe the area has changed */
111 if (fstat(shared_fd, &st)) goto failed;
113 if (st.st_size != shared_size) {
114 var = (char *)Realloc(variables, st.st_size);
115 if (!var) goto failed;
116 else variables = var;
117 shared_size = st.st_size;
118 lseek(shared_fd, 0, SEEK_SET);
119 if (read(shared_fd, variables, shared_size) != shared_size) {
120 goto failed;
124 unlockit();
126 i=0;
127 while (i < shared_size) {
128 char *n, *v;
129 int l1, l2;
131 l1 = SVAL(&variables[i], 0);
132 l2 = SVAL(&variables[i], 2);
134 n = &variables[i+4];
135 v = &variables[i+4+l1];
136 i += 4+l1+l2;
138 if (strcmp(name,n)) {
139 continue;
141 return v;
144 return NULL;
146 failed:
147 DEBUG(0,("smbw: shared variables corrupt (%s)\n", strerror(errno)));
148 exit(1);
149 return NULL;
154 /*****************************************************
155 set a variable in the shared area
156 *******************************************************/
157 void smbw_setshared(const char *name, const char *val)
159 int l1, l2;
160 char *var;
162 /* we don't allow variable overwrite */
163 if (smbw_getshared(name)) return;
165 lockit();
167 l1 = strlen(name)+1;
168 l2 = strlen(val)+1;
170 var = (char *)Realloc(variables, shared_size + l1+l2+4);
172 if (!var) {
173 DEBUG(0,("out of memory in smbw_setshared\n"));
174 exit(1);
177 variables = var;
179 SSVAL(&variables[shared_size], 0, l1);
180 SSVAL(&variables[shared_size], 2, l2);
182 safe_strcpy(&variables[shared_size] + 4, name, l1-1);
183 safe_strcpy(&variables[shared_size] + 4 + l1, val, l2-1);
185 shared_size += l1+l2+4;
187 lseek(shared_fd, 0, SEEK_SET);
188 if (write(shared_fd, variables, shared_size) != shared_size) {
189 DEBUG(0,("smbw_setshared failed (%s)\n", strerror(errno)));
190 exit(1);
193 unlockit();
197 /*****************************************************************
198 return true if the passed fd is the SMBW_HANDLE
199 *****************************************************************/
200 int smbw_shared_fd(int fd)
202 return (shared_fd && shared_fd == fd);