1/* 2 Unix SMB/CIFS implementation. 3 SMB wrapper functions - shared variables 4 Copyright (C) Andrew Tridgell 1998 5 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. 10 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. 15 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. 19*/ 20 21#include "includes.h" 22 23static int shared_fd; 24static char *variables; 25static int shared_size; 26 27/***************************************************** 28setup the shared area 29*******************************************************/ 30void smbw_setup_shared(void) 31{ 32 int fd; 33 pstring name, s; 34 35 slprintf(name,sizeof(name)-1, "%s/smbw.XXXXXX",tmpdir()); 36 37 fd = smb_mkstemp(name); 38 39 if (fd == -1) goto failed; 40 41 unlink(name); 42 43 shared_fd = set_maxfiles(SMBW_MAX_OPEN); 44 45 while (shared_fd && dup2(fd, shared_fd) != shared_fd) shared_fd--; 46 47 if (shared_fd == 0) goto failed; 48 49 close(fd); 50 51 DEBUG(4,("created shared_fd=%d\n", shared_fd)); 52 53 slprintf(s,sizeof(s)-1,"%d", shared_fd); 54 55 setenv("SMBW_HANDLE", s, 1); 56 57 return; 58 59 failed: 60 perror("Failed to setup shared variable area "); 61 exit(1); 62} 63 64static int locked; 65 66/***************************************************** 67lock the shared variable area 68*******************************************************/ 69static void lockit(void) 70{ 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); 76 } 77 shared_fd = atoi(p); 78 } 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); 83 } 84 locked++; 85} 86 87/***************************************************** 88unlock the shared variable area 89*******************************************************/ 90static void unlockit(void) 91{ 92 locked--; 93 if (locked == 0) { 94 fcntl_lock(shared_fd,SMB_F_SETLK,0,1,F_UNLCK); 95 } 96} 97 98 99/***************************************************** 100get a variable from the shared area 101*******************************************************/ 102char *smbw_getshared(const char *name) 103{ 104 int i; 105 struct stat st; 106 char *var; 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 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; 121 } 122 } 123 124 unlockit(); 125 126 i=0; 127 while (i < shared_size) { 128 char *n, *v; 129 int l1, l2; 130 131 l1 = SVAL(&variables[i], 0); 132 l2 = SVAL(&variables[i], 2); 133 134 n = &variables[i+4]; 135 v = &variables[i+4+l1]; 136 i += 4+l1+l2; 137 138 if (strcmp(name,n)) { 139 continue; 140 } 141 return v; 142 } 143 144 return NULL; 145 146 failed: 147 DEBUG(0,("smbw: shared variables corrupt (%s)\n", strerror(errno))); 148 exit(1); 149 return NULL; 150} 151 152 153 154/***************************************************** 155set a variable in the shared area 156*******************************************************/ 157void smbw_setshared(const char *name, const char *val) 158{ 159 int l1, l2; 160 char *var; 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 var = (char *)Realloc(variables, shared_size + l1+l2+4); 171 172 if (!var) { 173 DEBUG(0,("out of memory in smbw_setshared\n")); 174 exit(1); 175 } 176 177 variables = var; 178 179 SSVAL(&variables[shared_size], 0, l1); 180 SSVAL(&variables[shared_size], 2, l2); 181 182 safe_strcpy(&variables[shared_size] + 4, name, l1-1); 183 safe_strcpy(&variables[shared_size] + 4 + l1, val, l2-1); 184 185 shared_size += l1+l2+4; 186 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); 191 } 192 193 unlockit(); 194} 195 196 197/***************************************************************** 198return true if the passed fd is the SMBW_HANDLE 199*****************************************************************/ 200int smbw_shared_fd(int fd) 201{ 202 return (shared_fd && shared_fd == fd); 203} 204