1 | #include "urlib.h" |
1 | #include "urlib.h" |
2 | |
2 | |
3 | #include <fcntl.h> |
3 | #include <fcntl.h> |
|
|
4 | #include <stdio.h> |
|
|
5 | #include <string.h> |
|
|
6 | #include <stdlib.h> |
4 | |
7 | |
5 | #ifdef _WIN32 |
8 | #ifdef _WIN32 |
6 | |
9 | |
7 | #include <windows.h> |
10 | #include <windows.h> |
8 | //#include <winbase.h> |
11 | //#include <winbase.h> |
… | |
… | |
79 | #endif |
82 | #endif |
80 | |
83 | |
81 | #define u_16(ptr) (((ptr)[0] << 8) | (ptr)[1]) |
84 | #define u_16(ptr) (((ptr)[0] << 8) | (ptr)[1]) |
82 | #define u_32(ptr) (((ptr)[0] << 24) | ((ptr)[1] << 16) | ((ptr)[2] << 8) | (ptr)[3]) |
85 | #define u_32(ptr) (((ptr)[0] << 24) | ((ptr)[1] << 16) | ((ptr)[2] << 8) | (ptr)[3]) |
83 | |
86 | |
|
|
87 | static char currdir[MAX_PATH]; |
|
|
88 | static char datadir[MAX_PATH]; // %AppData%/urlader |
|
|
89 | static char exe_dir[MAX_PATH]; // %AppData%/urlader/EXE_ID |
|
|
90 | static char execdir[MAX_PATH]; // %AppData%/urlader/EXE_ID/EXE_VER |
|
|
91 | static char exe_id[MAX_PATH]; |
|
|
92 | static char exe_ver[MAX_PATH]; |
|
|
93 | |
|
|
94 | ///////////////////////////////////////////////////////////////////////////// |
|
|
95 | |
|
|
96 | static void |
|
|
97 | u_fatal (const char *msg) |
|
|
98 | { |
|
|
99 | #ifdef _WIN32 |
|
|
100 | MessageBox (0, msg, URLADER, 0); |
|
|
101 | #else |
|
|
102 | write (2, URLADER ": ", sizeof (URLADER ": ") - 1); |
|
|
103 | write (2, msg, strlen (msg)); |
|
|
104 | write (2, "\n", 1); |
|
|
105 | #endif |
|
|
106 | |
|
|
107 | _exit (1); |
|
|
108 | } |
|
|
109 | |
84 | static void * |
110 | static void * |
85 | u_malloc (unsigned int size) |
111 | u_malloc (unsigned int size) |
86 | { |
112 | { |
87 | void *addr; |
113 | void *addr; |
88 | |
114 | |
|
|
115 | if (!size) |
|
|
116 | return 0; |
|
|
117 | |
89 | #ifdef _WIN32 |
118 | #ifdef _WIN32 |
90 | HANDLE handle = CreateFileMapping (0, 0, PAGE_READWRITE, 0, size, NULL); |
119 | HANDLE handle = CreateFileMapping (0, 0, PAGE_READWRITE, 0, size, NULL); |
91 | |
120 | |
|
|
121 | addr = 0; |
92 | if (!handle) |
122 | if (handle) |
93 | return 0; |
123 | { |
94 | |
|
|
95 | addr = MapViewOfFile (handle, FILE_MAP_WRITE, 0, 0, size); |
124 | addr = MapViewOfFile (handle, FILE_MAP_WRITE, 0, 0, size); |
96 | |
|
|
97 | CloseHandle (handle); |
125 | CloseHandle (handle); |
|
|
126 | } |
98 | #elif defined (MAP_ANONYMOUS) |
127 | #elif defined (MAP_ANONYMOUS) |
99 | addr = mmap (0, size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON, -1, 0); |
128 | addr = mmap (0, size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON, -1, 0); |
100 | |
129 | |
101 | if (addr == (void *)-1) |
130 | if (addr == (void *)-1) |
102 | addr = 0; |
131 | addr = 0; |
103 | #else |
132 | #else |
104 | addr = malloc (size); |
133 | addr = malloc (size); |
105 | #endif |
134 | #endif |
106 | |
135 | |
|
|
136 | if (!addr) |
|
|
137 | u_fatal ("memory allocation failure, aborting."); |
|
|
138 | |
107 | return addr; |
139 | return addr; |
108 | } |
140 | } |
109 | |
141 | |
110 | static void |
142 | static void |
111 | u_free (void *addr, unsigned int size) |
143 | u_free (void *addr, unsigned int size) |
112 | { |
144 | { |
|
|
145 | if (!addr) |
|
|
146 | return; |
|
|
147 | |
113 | #ifdef _WIN32 |
148 | #ifdef _WIN32 |
114 | UnmapViewOfFile (addr); |
149 | UnmapViewOfFile (addr); |
115 | #elif defined (MAP_ANONYMOUS) |
150 | #elif defined (MAP_ANONYMOUS) |
116 | munmap (addr, size); |
151 | munmap (addr, size); |
117 | #else |
152 | #else |
118 | free (addr); |
153 | free (addr); |
119 | #endif |
154 | #endif |
120 | } |
155 | } |
121 | |
156 | |
122 | static void * |
157 | static void * |
|
|
158 | u_realloc (void *addr, unsigned int old_size, unsigned int new_size) |
|
|
159 | { |
|
|
160 | void *addr2 = u_malloc (new_size); |
|
|
161 | memcpy (addr2, addr, (new_size < old_size ? new_size : old_size)); |
|
|
162 | u_free (addr, old_size); |
|
|
163 | |
|
|
164 | return addr2; |
|
|
165 | } |
|
|
166 | |
|
|
167 | static void * |
123 | u_mmap (u_handle h, unsigned int size) |
168 | u_mmap (u_handle h, unsigned int size) |
124 | { |
169 | { |
125 | void *addr; |
170 | void *addr; |
126 | |
171 | |
127 | #ifdef _WIN32 |
172 | #ifdef _WIN32 |
… | |
… | |
150 | UnmapViewOfFile (addr); |
195 | UnmapViewOfFile (addr); |
151 | #else |
196 | #else |
152 | munmap (addr, len); |
197 | munmap (addr, len); |
153 | #endif |
198 | #endif |
154 | } |
199 | } |
|
|
200 | |
|
|
201 | ///////////////////////////////////////////////////////////////////////////// |
|
|
202 | |
|
|
203 | typedef struct |
|
|
204 | { |
|
|
205 | char *addr; |
|
|
206 | unsigned int used; |
|
|
207 | unsigned int size; |
|
|
208 | } u_dynbuf; |
|
|
209 | |
|
|
210 | static void * |
|
|
211 | u_dynbuf_append (u_dynbuf *dynbuf, void *data, unsigned int len) |
|
|
212 | { |
|
|
213 | char *dest; |
|
|
214 | |
|
|
215 | if ((dynbuf->used += len) > dynbuf->size) |
|
|
216 | { |
|
|
217 | unsigned int new_size = dynbuf->size ? dynbuf->size * 2 : 4096; |
|
|
218 | dynbuf->addr = u_realloc (dynbuf->addr, dynbuf->size, new_size); |
|
|
219 | dynbuf->size = new_size; |
|
|
220 | } |
|
|
221 | |
|
|
222 | dest = dynbuf->addr + dynbuf->used - len; |
|
|
223 | |
|
|
224 | if (data) |
|
|
225 | memcpy (dest, data, len); |
|
|
226 | |
|
|
227 | return dest; |
|
|
228 | } |
|
|
229 | |
|
|
230 | ///////////////////////////////////////////////////////////////////////////// |
|
|
231 | |
|
|
232 | static void |
|
|
233 | u_set_datadir (void) |
|
|
234 | { |
|
|
235 | #ifdef _WIN32 |
|
|
236 | if (SHGetFolderPath (0, CSIDL_APPDATA | CSIDL_FLAG_CREATE, NULL, SHGFP_TYPE_CURRENT, datadir) != S_OK) |
|
|
237 | u_fatal ("unable to find application data directory"); |
|
|
238 | |
|
|
239 | u_mkdir (datadir); |
|
|
240 | u_append (datadir, URLADER); |
|
|
241 | |
|
|
242 | #else |
|
|
243 | char *home = getenv ("HOME"); |
|
|
244 | |
|
|
245 | if (!home) |
|
|
246 | { |
|
|
247 | struct passwd *pw; |
|
|
248 | |
|
|
249 | if ((pw = getpwuid (getuid ()))) |
|
|
250 | home = pw->pw_dir; |
|
|
251 | else |
|
|
252 | home = "/tmp"; |
|
|
253 | } |
|
|
254 | |
|
|
255 | u_mkdir (home); |
|
|
256 | //strcat (strcat (strcpy (datadir, home), "/."), URLADER); |
|
|
257 | sprintf (datadir, "%s/.%s", home, URLADER); |
|
|
258 | #endif |
|
|
259 | |
|
|
260 | u_setenv ("URLADER_DATADIR", datadir); |
|
|
261 | } |
|
|
262 | |
|
|
263 | static void |
|
|
264 | u_set_exe_info (void) |
|
|
265 | { |
|
|
266 | strcpy (exe_dir, datadir); |
|
|
267 | u_append (exe_dir, exe_id); |
|
|
268 | u_mkdir (exe_dir); |
|
|
269 | |
|
|
270 | strcpy (execdir, exe_dir); |
|
|
271 | u_append (execdir, "i-"); |
|
|
272 | strcat (execdir, exe_ver); |
|
|
273 | |
|
|
274 | u_setenv ("URLADER_EXECDIR", execdir); |
|
|
275 | u_setenv ("URLADER_EXE_ID" , exe_id); |
|
|
276 | u_setenv ("URLADER_EXE_DIR", exe_dir); |
|
|
277 | u_setenv ("URLADER_EXE_VER", exe_ver); |
|
|
278 | } |
|
|
279 | |
|
|
280 | ///////////////////////////////////////////////////////////////////////////// |
|
|
281 | |
155 | static u_handle |
282 | static u_handle |
156 | u_lock (const char *path, int excl, int dowait) |
283 | u_lock (const char *path, int excl, int dowait) |
157 | { |
284 | { |
158 | u_handle h; |
285 | u_handle h; |
159 | |
286 | |
… | |
… | |
192 | |
319 | |
193 | // we have the lock, now verify that the lockfile still exists |
320 | // we have the lock, now verify that the lockfile still exists |
194 | |
321 | |
195 | #ifdef _WIN32 |
322 | #ifdef _WIN32 |
196 | // apparently, we have to open the file to get its info :( |
323 | // apparently, we have to open the file to get its info :( |
|
|
324 | { |
197 | BY_HANDLE_FILE_INFORMATION s1, s2; |
325 | BY_HANDLE_FILE_INFORMATION s1, s2; |
198 | u_handle h2 = u_lockfile (path); |
326 | u_handle h2 = u_lockfile (path); |
199 | if (!u_valid (h)) |
327 | if (!u_valid (h)) |
200 | break; |
328 | break; |
201 | |
329 | |
202 | success = GetFileInformationByHandle (h, &s1) |
330 | success = GetFileInformationByHandle (h, &s1) |
203 | && GetFileInformationByHandle (h2, &s2); |
331 | && GetFileInformationByHandle (h2, &s2); |
204 | |
332 | |
205 | u_close (h2); |
333 | u_close (h2); |
206 | |
334 | |
207 | if (!success) |
335 | if (!success) |
208 | break; |
336 | break; |
209 | |
337 | |
210 | success = s1.dwVolumeSerialNumber == s2.dwVolumeSerialNumber |
338 | success = s1.dwVolumeSerialNumber == s2.dwVolumeSerialNumber |
211 | && s1.nFileIndexHigh == s2.nFileIndexHigh |
339 | && s1.nFileIndexHigh == s2.nFileIndexHigh |
212 | && s1.nFileIndexLow == s2.nFileIndexLow; |
340 | && s1.nFileIndexLow == s2.nFileIndexLow; |
|
|
341 | } |
213 | #else |
342 | #else |
214 | struct stat s1, s2; |
343 | struct stat s1, s2; |
215 | |
344 | |
216 | if (fstat (h, &s1) || stat (path, &s2)) |
345 | if (fstat (h, &s1) || stat (path, &s2)) |
217 | break; |
346 | break; |