Removed 'extern int DEBUGLEVEL' as it is now in the smb.h header.
[samba.git] / source3 / smbwrapper / shared.c
1 /* 
2    Unix SMB/Netbios implementation.
3    Version 2.0
4    SMB wrapper functions - shared variables
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 static int shared_fd;
25 static char *variables;
26 static int shared_size;
27
28 /***************************************************** 
29 setup the shared area 
30 *******************************************************/
31 void smbw_setup_shared(void)
32 {
33         int fd;
34         pstring name, s;
35
36         slprintf(name,sizeof(name)-1, "%s/smbw.XXXXXX",tmpdir());
37
38         fd = smb_mkstemp(name);
39
40         if (fd == -1) goto failed;
41
42         unlink(name);
43
44         shared_fd = set_maxfiles(SMBW_MAX_OPEN);
45         
46         while (shared_fd && dup2(fd, shared_fd) != shared_fd) shared_fd--;
47
48         if (shared_fd == 0) goto failed;
49
50         close(fd);
51
52         DEBUG(4,("created shared_fd=%d\n", shared_fd));
53
54         slprintf(s,sizeof(s)-1,"%d", shared_fd);
55
56         smbw_setenv("SMBW_HANDLE", s);
57
58         return;
59
60  failed:
61         perror("Failed to setup shared variable area ");
62         exit(1);
63 }
64
65 static int locked;
66
67 /***************************************************** 
68 lock the shared variable area
69 *******************************************************/
70 static void lockit(void)
71 {
72         if (shared_fd == 0) {
73                 char *p = getenv("SMBW_HANDLE");
74                 if (!p) {
75                         DEBUG(0,("ERROR: can't get smbw shared handle\n"));
76                         exit(1);
77                 }
78                 shared_fd = atoi(p);
79         }
80         if (locked==0 && 
81             fcntl_lock(shared_fd,SMB_F_SETLKW,0,1,F_WRLCK)==False) {
82                 DEBUG(0,("ERROR: can't get smbw shared lock (%s)\n", strerror(errno)));
83                 exit(1);
84         }
85         locked++;
86 }
87
88 /***************************************************** 
89 unlock the shared variable area
90 *******************************************************/
91 static void unlockit(void)
92 {
93         locked--;
94         if (locked == 0) {
95                 fcntl_lock(shared_fd,SMB_F_SETLK,0,1,F_UNLCK);
96         }
97 }
98
99
100 /***************************************************** 
101 get a variable from the shared area
102 *******************************************************/
103 char *smbw_getshared(const char *name)
104 {
105         int i;
106         struct stat st;
107
108         lockit();
109
110         /* maybe the area has changed */
111         if (fstat(shared_fd, &st)) goto failed;
112
113         if (st.st_size != shared_size) {
114                 variables = (char *)Realloc(variables, st.st_size);
115                 if (!variables) goto failed;
116                 shared_size = st.st_size;
117                 lseek(shared_fd, 0, SEEK_SET);
118                 if (read(shared_fd, variables, shared_size) != shared_size) {
119                         goto failed;
120                 }
121         }
122
123         unlockit();
124
125         i=0;
126         while (i < shared_size) {
127                 char *n, *v;
128                 int l1, l2;
129
130                 l1 = SVAL(&variables[i], 0);
131                 l2 = SVAL(&variables[i], 2);
132
133                 n = &variables[i+4];
134                 v = &variables[i+4+l1];
135                 i += 4+l1+l2;
136
137                 if (strcmp(name,n)) {
138                         continue;
139                 }
140                 return v;
141         }
142
143         return NULL;
144
145  failed:
146         DEBUG(0,("smbw: shared variables corrupt (%s)\n", strerror(errno)));
147         exit(1);
148         return NULL;
149 }
150
151
152
153 /***************************************************** 
154 set a variable in the shared area
155 *******************************************************/
156 void smbw_setshared(const char *name, const char *val)
157 {
158         int l1, l2;
159
160         /* we don't allow variable overwrite */
161         if (smbw_getshared(name)) return;
162
163         lockit();
164
165         l1 = strlen(name)+1;
166         l2 = strlen(val)+1;
167
168         variables = (char *)Realloc(variables, shared_size + l1+l2+4);
169
170         if (!variables) {
171                 DEBUG(0,("out of memory in smbw_setshared\n"));
172                 exit(1);
173         }
174
175         SSVAL(&variables[shared_size], 0, l1);
176         SSVAL(&variables[shared_size], 2, l2);
177
178         pstrcpy(&variables[shared_size] + 4, name);
179         pstrcpy(&variables[shared_size] + 4 + l1, val);
180
181         shared_size += l1+l2+4;
182
183         lseek(shared_fd, 0, SEEK_SET);
184         if (write(shared_fd, variables, shared_size) != shared_size) {
185                 DEBUG(0,("smbw_setshared failed (%s)\n", strerror(errno)));
186                 exit(1);
187         }
188
189         unlockit();
190 }
191
192
193 /*****************************************************************
194 set an env variable - some systems don't have this
195 *****************************************************************/  
196 int smbw_setenv(const char *name, const char *value)
197 {
198         pstring s;
199         char *p;
200         int ret = -1;
201
202         slprintf(s,sizeof(s)-1,"%s=%s", name, value);
203
204         p = strdup(s);
205
206         if (p) ret = putenv(p);
207
208         return ret;
209 }
210
211 /*****************************************************************
212 return true if the passed fd is the SMBW_HANDLE
213 *****************************************************************/  
214 int smbw_shared_fd(int fd)
215 {
216         return (shared_fd && shared_fd == fd);
217 }