fixed bug in for/do/while/switch
[swftools.git] / lib / os.c
1 /* os.c
2
3 operating system dependent functions
4
5 Part of the swftools package. 
6
7 Copyright (c) 2005 Matthias Kramm <kramm@quiss.org>
8
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2 of the License, or
12 (at your option) any later version.
13
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17 GNU General Public License for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
22
23 #include "os.h"
24 #include <stdlib.h>
25 #include <stdio.h>
26 #include <string.h>
27 #ifdef WIN32
28 #include <windows.h>
29 #else
30 #include <unistd.h>
31 #include <fcntl.h>
32 #endif
33 #ifdef HAVE_SYS_STAT_H
34 #include <sys/stat.h>
35 #else
36 #undef HAVE_STAT
37 #endif
38 #ifdef HAVE_SYS_MMAN_H
39 #include <sys/mman.h>
40 #else
41 #undef HAVE_MMAP
42 #endif
43 #ifdef HAVE_SYS_TYPES_H
44 #include <sys/types.h>
45 #else
46 #undef HAVE_STAT
47 #endif
48
49 #if defined(CYGWIN)
50 static char seperator = '/';
51 #elif defined(WIN32)
52 static char seperator = '\\';
53 #else
54 static char seperator = '/';
55 #endif
56
57 #ifdef WIN32
58 char* getRegistryEntry(char*path)
59 {
60     int res = 0;
61     HKEY key;
62     long rc;
63     long size = 0;
64     DWORD type;
65     char*buf;
66     rc = RegOpenKeyEx(HKEY_CURRENT_USER, path, 0, KEY_ALL_ACCESS, &key);
67     if(rc)
68         rc = RegOpenKeyEx(HKEY_CURRENT_USER, path, 0, KEY_READ, &key);
69     if(rc)
70         rc = RegOpenKeyEx(HKEY_LOCAL_MACHINE, path, 0, KEY_ALL_ACCESS, &key);
71     if(rc)
72         rc = RegOpenKeyEx(HKEY_LOCAL_MACHINE, path, 0, KEY_READ, &key);
73
74     if (rc) {
75         fprintf(stderr, "RegOpenKeyEx failed\n");
76         return 0;
77     }
78     rc = RegQueryValueEx(key, NULL, 0, 0, 0, (LPDWORD)&size) ;
79     if(rc) {
80         fprintf(stderr, "RegQueryValueEx(1) failed: %d\n", rc);
81         return 0;
82     }
83     buf = (char*)malloc(size+1);
84     rc = RegQueryValueEx(key, NULL, 0, &type, (BYTE*)buf, (LPDWORD)&size);
85     if(rc) {
86         fprintf(stderr, "RegQueryValueEx(2) failed: %d\n", rc);
87         return 0;
88     }
89     if(type == REG_SZ || type == REG_EXPAND_SZ) {
90         while(size && buf[size-1] == '\0')
91           --size;
92         buf[size] = 0;
93         /* TODO: convert */
94         return buf;
95     } else if(type == REG_BINARY) {
96         return buf;
97     }
98     return 0;
99 }
100
101 int setRegistryEntry(char*key,char*value)
102 {
103     HKEY hkey1;
104     HKEY hkey2;
105     int ret1 = 0, ret2=0;
106     ret1 = RegCreateKey(HKEY_CURRENT_USER, key, &hkey1);
107     ret2 = RegCreateKey(HKEY_LOCAL_MACHINE, key, &hkey2);
108     if(ret1 && ret2) {
109         fprintf(stderr, "registry: CreateKey %s failed\n", key);
110         return 0;
111     }
112     if(!ret1)
113         ret1 = RegSetValue(hkey1, NULL, REG_SZ, value, strlen(value)+1);
114     if(!ret2)
115         ret2 = RegSetValue(hkey2, NULL, REG_SZ, value, strlen(value)+1);
116     if(ret1 && ret2) {
117         fprintf(stderr, "registry: SetValue %s failed\n", key);
118         return 0;
119     }
120     return 1;
121 }
122
123
124 #endif
125
126 //HINSTANCE me =  GetModuleHandle(NULL);
127
128 char* getInstallationPath()
129 {
130 #if defined(WIN32)
131     char* path = getRegistryEntry("Software\\quiss.org\\swftools\\InstallPath");
132     if(path)
133         return path;
134     else
135         return 0;
136 #elif defined(CYGWIN)
137     return SWFTOOLS_DATADIR;
138 #else
139     return SWFTOOLS_DATADIR;
140 #endif
141 }
142
143 char* concatPaths(const char*base, const char*add)
144 {
145     int l1 = strlen(base);
146     int l2 = strlen(add);
147     int pos = 0;
148     char*n = 0;
149     while(l1 && base[l1-1] == seperator)
150         l1--;
151     while(pos < l2 && add[pos] == seperator)
152         pos++;
153
154     n = (char*)malloc(l1 + (l2-pos) + 2);
155     memcpy(n,base,l1);
156     n[l1]=seperator;
157     strcpy(&n[l1+1],&add[pos]);
158     return n;
159 }
160
161 char* stripFilename(const char*filename, const char*newext)
162 {
163     char*last1 = strrchr(filename, '/');
164     char*last2 = strrchr(filename, '\\');
165     const char*pos = filename;
166     char*name;
167     char*dot;
168     if(last1>pos) pos = last1 + 1;
169     if(last2>pos) pos = last2 + 1;
170     name = (char*)malloc(strlen(pos)+2+(newext?strlen(newext):3));
171     strcpy(name, pos);
172     dot = strrchr(name, '.');
173     if(dot) {
174         *dot = 0;
175     }
176     if(newext)
177         strcat(name, newext);
178     return name;
179 }
180
181 static char* getTempDir()
182 {
183 #ifdef WIN32
184     char*dir = getenv("TMP");
185     if(!dir) dir = getenv("TEMP");
186     if(!dir) dir = getenv("tmp");
187     if(!dir) dir = getenv("temp");
188     if(!dir) dir = "C:\\";
189 #else
190     char* dir = "/tmp/";
191 #endif
192     return dir;
193 }
194
195 char* mktempname(char*ptr) {
196     static char tmpbuf[128];
197     char*dir = getTempDir();
198     int l = strlen(dir);
199     char*sep = "";
200     if(!ptr)
201         ptr = tmpbuf;
202     if(l && dir[l-1]!='/' && dir[l-1]!='\\') {
203 #ifdef WIN32
204         sep = "\\";
205 #else
206         sep = "/";
207 #endif
208     }
209
210  //   used to be mktemp. This does remove the warnings, but
211  //   It's not exactly an improvement.
212 #ifdef HAVE_LRAND48
213     sprintf(ptr, "%s%s%08x%08x",dir,sep,lrand48(),lrand48());
214 #else
215 #   ifdef HAVE_RAND
216         sprintf(ptr, "%s%s%08x%08x",dir,sep,rand(),rand());
217 #   else
218         static int count = 1;
219         sprintf(ptr, "%s%s%08x%04x%04x",dir,sep,time(0),(unsigned int)tmpbuf^((unsigned int)tmpbuf)>>16,count);
220         count ++;
221 #   endif
222 #endif
223      return ptr;
224 }
225
226 memfile_t* memfile_open(const char*path)
227 {
228     memfile_t*file = malloc(sizeof(memfile_t));
229 #if defined(HAVE_MMAP) && defined(HAVE_STAT)
230     int fi = open(path, O_RDONLY);
231     if(fi<0) {
232         perror(path);
233         free(file);
234         return 0;
235     }
236     struct stat sb;
237     if(fstat(fi, &sb)<0) {
238         perror(path);
239         return 0;
240     }
241     file->len = sb.st_size;
242     file->data = mmap(0, sb.st_size, PROT_READ, MAP_PRIVATE, fi, 0);
243 #else
244     FILE*fi = fopen(path, "rb");
245     if(!fi) {
246         perror(path);
247         free(file);
248         return 0;
249     }
250     fseek(fi, 0, SEEK_END);
251     file->len = ftell(fi);
252     fseek(fi, 0, SEEK_SET);
253     file->data = malloc(file->len);
254     if(!file->data) {
255         fprintf(stderr, "Out of memory while allocating memory for file %s\n", path);
256         free(file);
257         return 0;
258     }
259     fread(file->data, file->len, 1, fi);
260     fclose(fi);
261 #endif
262     return file;
263 }
264
265 void memfile_close(memfile_t*file)
266 {
267 #if defined(HAVE_MMAP) && defined(HAVE_STAT)
268     munmap(file->data, file->len);
269 #else
270     free(file->data);
271 #endif
272     file->data = file->len = 0;
273     free(file);
274 }
275