+static char* getTempDir()
+{
+#ifdef WIN32
+ char*dir = getenv("TMP");
+ if(!dir) dir = getenv("TEMP");
+ if(!dir) dir = getenv("tmp");
+ if(!dir) dir = getenv("temp");
+ if(!dir) dir = "C:\\";
+#else
+ char* dir = "/tmp/";
+#endif
+ return dir;
+}
+
+char* mktempname(char*ptr, const char*ext) {
+ static char tmpbuf[160];
+ char*dir = getTempDir();
+ int l = strlen(dir);
+ char*sep = "";
+ if(!ptr)
+ ptr = tmpbuf;
+ if(l && dir[l-1]!='/' && dir[l-1]!='\\') {
+#ifdef WIN32
+ sep = "\\";
+#else
+ sep = "/";
+#endif
+ }
+
+#ifdef HAVE_LRAND48
+ unsigned int r1 = (unsigned int)lrand48();
+ unsigned int r2 = (unsigned int)lrand48();
+#elif HAVE_RAND
+ unsigned int r1 = rand();
+ unsigned int r2 = rand();
+#else
+ static int count = 1;
+ unsigned int r1 = time(0);
+ unsigned int r2 = (unsigned int)tmpbuf<<8^count;
+ count ++;
+#endif
+ if(ext) {
+ sprintf(ptr, "%s%s%04x%04x.%s",dir,sep,r1,r2,ext);
+ } else {
+ sprintf(ptr, "%s%s%04x%04x",dir,sep,r1,r2);
+ }
+ return ptr;
+}
+
+memfile_t* memfile_open(const char*path)
+{
+ memfile_t*file = malloc(sizeof(memfile_t));
+#if defined(HAVE_MMAP) && defined(HAVE_STAT)
+ int fi = open(path, O_RDONLY);
+ if(fi<0) {
+ perror(path);
+ free(file);
+ return 0;
+ }
+ struct stat sb;
+ if(fstat(fi, &sb)<0) {
+ perror(path);
+ return 0;
+ }
+ file->len = sb.st_size;
+ file->data = mmap(0, sb.st_size, PROT_READ, MAP_PRIVATE, fi, 0);
+#else
+ FILE*fi = fopen(path, "rb");
+ if(!fi) {
+ perror(path);
+ free(file);
+ return 0;
+ }
+ fseek(fi, 0, SEEK_END);
+ file->len = ftell(fi);
+ fseek(fi, 0, SEEK_SET);
+ file->data = malloc(file->len);
+ if(!file->data) {
+ fprintf(stderr, "Out of memory while allocating memory for file %s\n", path);
+ free(file);
+ return 0;
+ }
+ fread(file->data, file->len, 1, fi);
+ fclose(fi);
+#endif
+ return file;
+}
+
+void memfile_close(memfile_t*file)
+{
+#if defined(HAVE_MMAP) && defined(HAVE_STAT)
+ munmap(file->data, file->len);
+#else
+ free(file->data);
+#endif
+ file->data = 0;
+ file->len = 0;
+ free(file);
+}
+
+void move_file(const char*from, const char*to)
+{
+ int result = rename(from, to);
+
+ if(result==0) return; //done!
+
+ /* if we can't rename, for some reason, copy the file
+ manually */
+ FILE*fi = fopen(from, "rb");
+ if(!fi) {
+ perror(from);
+ return;
+ }
+ FILE*fo = fopen(to, "wb");
+ if(!fo) {
+ perror(to);
+ return;
+ }
+ char buffer[16384];
+ while(1) {
+ int bytes = fread(buffer, 16384, 1, fi);
+ if(bytes<=0)
+ return;
+ fwrite(buffer, bytes, 1, fo);
+ }
+
+ fclose(fo);
+ fclose(fi);
+}
+