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