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