--- Urlader/urlib.c 2011/12/30 23:34:08 1.1 +++ Urlader/urlib.c 2012/01/06 07:56:36 1.3 @@ -1,6 +1,9 @@ #include "urlib.h" #include +#include +#include +#include #ifdef _WIN32 @@ -81,20 +84,46 @@ #define u_16(ptr) (((ptr)[0] << 8) | (ptr)[1]) #define u_32(ptr) (((ptr)[0] << 24) | ((ptr)[1] << 16) | ((ptr)[2] << 8) | (ptr)[3]) +static char currdir[MAX_PATH]; +static char datadir[MAX_PATH]; // %AppData%/urlader +static char exe_dir[MAX_PATH]; // %AppData%/urlader/EXE_ID +static char execdir[MAX_PATH]; // %AppData%/urlader/EXE_ID/EXE_VER +static char exe_id[MAX_PATH]; +static char exe_ver[MAX_PATH]; + +///////////////////////////////////////////////////////////////////////////// + +static void +u_fatal (const char *msg) +{ +#ifdef _WIN32 + MessageBox (0, msg, URLADER, 0); +#else + write (2, URLADER ": ", sizeof (URLADER ": ") - 1); + write (2, msg, strlen (msg)); + write (2, "\n", 1); +#endif + + _exit (1); +} + static void * u_malloc (unsigned int size) { void *addr; -#ifdef _WIN32 - HANDLE handle = CreateFileMapping (0, 0, PAGE_READWRITE, 0, size, NULL); - - if (!handle) + if (!size) return 0; - addr = MapViewOfFile (handle, FILE_MAP_WRITE, 0, 0, size); +#ifdef _WIN32 + HANDLE handle = CreateFileMapping (0, 0, PAGE_READWRITE, 0, size, NULL); - CloseHandle (handle); + addr = 0; + if (handle) + { + addr = MapViewOfFile (handle, FILE_MAP_WRITE, 0, 0, size); + CloseHandle (handle); + } #elif defined (MAP_ANONYMOUS) addr = mmap (0, size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON, -1, 0); @@ -104,12 +133,18 @@ addr = malloc (size); #endif + if (!addr) + u_fatal ("memory allocation failure, aborting."); + return addr; } static void u_free (void *addr, unsigned int size) { + if (!addr) + return; + #ifdef _WIN32 UnmapViewOfFile (addr); #elif defined (MAP_ANONYMOUS) @@ -120,6 +155,16 @@ } static void * +u_realloc (void *addr, unsigned int old_size, unsigned int new_size) +{ + void *addr2 = u_malloc (new_size); + memcpy (addr2, addr, (new_size < old_size ? new_size : old_size)); + u_free (addr, old_size); + + return addr2; +} + +static void * u_mmap (u_handle h, unsigned int size) { void *addr; @@ -152,6 +197,88 @@ munmap (addr, len); #endif } + +///////////////////////////////////////////////////////////////////////////// + +typedef struct +{ + char *addr; + unsigned int used; + unsigned int size; +} u_dynbuf; + +static void * +u_dynbuf_append (u_dynbuf *dynbuf, void *data, unsigned int len) +{ + char *dest; + + if ((dynbuf->used += len) > dynbuf->size) + { + unsigned int new_size = dynbuf->size ? dynbuf->size * 2 : 4096; + dynbuf->addr = u_realloc (dynbuf->addr, dynbuf->size, new_size); + dynbuf->size = new_size; + } + + dest = dynbuf->addr + dynbuf->used - len; + + if (data) + memcpy (dest, data, len); + + return dest; +} + +///////////////////////////////////////////////////////////////////////////// + +static void +u_set_datadir (void) +{ +#ifdef _WIN32 + if (SHGetFolderPath (0, CSIDL_APPDATA | CSIDL_FLAG_CREATE, NULL, SHGFP_TYPE_CURRENT, datadir) != S_OK) + u_fatal ("unable to find application data directory"); + + u_mkdir (datadir); + u_append (datadir, URLADER); + +#else + char *home = getenv ("HOME"); + + if (!home) + { + struct passwd *pw; + + if ((pw = getpwuid (getuid ()))) + home = pw->pw_dir; + else + home = "/tmp"; + } + + u_mkdir (home); + //strcat (strcat (strcpy (datadir, home), "/."), URLADER); + sprintf (datadir, "%s/.%s", home, URLADER); +#endif + + u_setenv ("URLADER_DATADIR", datadir); +} + +static void +u_set_exe_info (void) +{ + strcpy (exe_dir, datadir); + u_append (exe_dir, exe_id); + u_mkdir (exe_dir); + + strcpy (execdir, exe_dir); + u_append (execdir, "i-"); + strcat (execdir, exe_ver); + + u_setenv ("URLADER_EXECDIR", execdir); + u_setenv ("URLADER_EXE_ID" , exe_id); + u_setenv ("URLADER_EXE_DIR", exe_dir); + u_setenv ("URLADER_EXE_VER", exe_ver); +} + +///////////////////////////////////////////////////////////////////////////// + static u_handle u_lock (const char *path, int excl, int dowait) { @@ -194,22 +321,24 @@ #ifdef _WIN32 // apparently, we have to open the file to get its info :( - BY_HANDLE_FILE_INFORMATION s1, s2; - u_handle h2 = u_lockfile (path); - if (!u_valid (h)) - break; - - success = GetFileInformationByHandle (h, &s1) - && GetFileInformationByHandle (h2, &s2); - - u_close (h2); - - if (!success) - break; - - success = s1.dwVolumeSerialNumber == s2.dwVolumeSerialNumber - && s1.nFileIndexHigh == s2.nFileIndexHigh - && s1.nFileIndexLow == s2.nFileIndexLow; + { + BY_HANDLE_FILE_INFORMATION s1, s2; + u_handle h2 = u_lockfile (path); + if (!u_valid (h)) + break; + + success = GetFileInformationByHandle (h, &s1) + && GetFileInformationByHandle (h2, &s2); + + u_close (h2); + + if (!success) + break; + + success = s1.dwVolumeSerialNumber == s2.dwVolumeSerialNumber + && s1.nFileIndexHigh == s2.nFileIndexHigh + && s1.nFileIndexLow == s2.nFileIndexLow; + } #else struct stat s1, s2;