* Hope this is the last bug fix in the wxThread merge ...
[wxWidgets.git] / src / gtk1 / utilsgtk.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: utils.cpp
3 // Purpose:
4 // Author: Robert Roebling
5 // Created: 01/02/97
6 // Id:
7 // Copyright: (c) 1998 Robert Roebling, Julian Smart and Markus Holzem
8 // Licence: wxWindows licence
9 /////////////////////////////////////////////////////////////////////////////
10
11
12 //#ifdef __GNUG__
13 //#pragma implementation "utils.h"
14 //#endif
15
16 #include "wx/utils.h"
17 #include "wx/string.h"
18
19 #include <stdarg.h>
20 #include <dirent.h>
21 #include <string.h>
22 #include <sys/stat.h>
23 #include <sys/types.h>
24 #include <unistd.h>
25 #include <sys/wait.h>
26 #include <pwd.h>
27 #include <errno.h>
28 #include <netdb.h>
29 #include <signal.h>
30
31 #ifdef __SVR4__
32 #include <sys/systeminfo.h>
33 #endif
34
35 //------------------------------------------------------------------------
36 // misc.
37 //------------------------------------------------------------------------
38
39 void wxBell(void)
40 {
41 gdk_beep();
42 };
43
44 void wxSleep(int nSecs)
45 {
46 sleep(nSecs);
47 };
48
49 int wxKill(long pid, int sig)
50 {
51 return kill(pid, sig);
52 };
53
54 //------------------------------------------------------------------------
55 // user and home routines
56 //------------------------------------------------------------------------
57
58 char* wxGetHomeDir( char *dest )
59 {
60 wxString tmp = wxGetUserHome( wxString() );
61 if (tmp.IsNull())
62 strcpy( wxBuffer, "/" );
63 else
64 strcpy( wxBuffer, tmp );
65 if (dest) strcpy( dest, WXSTRINGCAST tmp );
66 return wxBuffer;
67 };
68
69 char *wxGetUserHome( const wxString &user )
70 {
71 struct passwd *who = NULL;
72
73 if (user.IsNull() || (user== ""))
74 {
75 register char *ptr;
76
77 if ((ptr = getenv("HOME")) != NULL)
78 return ptr;
79 if ((ptr = getenv("USER")) != NULL
80 || (ptr = getenv("LOGNAME")) != NULL) {
81 who = getpwnam(ptr);
82 }
83 // We now make sure the the user exists!
84 if (who == NULL)
85 who = getpwuid(getuid());
86 }
87 else
88 who = getpwnam (user);
89
90 return who ? who->pw_dir : (char*)NULL;
91 };
92
93 //------------------------------------------------------------------------
94 // id routines
95 //------------------------------------------------------------------------
96
97 bool wxGetHostName(char *buf, int sz)
98 {
99 *buf = '\0';
100 #if defined(__SVR4__) && !defined(__sgi)
101 return (sysinfo(SI_HOSTNAME, buf, sz) != -1);
102 #else /* BSD Sockets */
103 char name[255];
104 struct hostent *h;
105 // Get hostname
106 if (gethostname(name, sizeof(name)/sizeof(char)-1) == -1)
107 return FALSE;
108 // Get official full name of host
109 strncpy(buf, (h=gethostbyname(name))!=NULL ? h->h_name : name, sz-1);
110 return TRUE;
111 #endif
112 }
113
114 bool wxGetUserId(char *buf, int sz)
115 {
116 struct passwd *who;
117
118 *buf = '\0';
119 if ((who = getpwuid(getuid ())) != NULL) {
120 strncpy (buf, who->pw_name, sz-1);
121 return TRUE;
122 }
123 return FALSE;
124 }
125
126 bool wxGetUserName(char *buf, int sz)
127 {
128 struct passwd *who;
129
130 *buf = '\0';
131 if ((who = getpwuid (getuid ())) != NULL) {
132 strncpy (buf, who->pw_gecos, sz - 1);
133 return TRUE;
134 }
135 return FALSE;
136 }
137
138 //------------------------------------------------------------------------
139 // error and debug output routines
140 //------------------------------------------------------------------------
141
142 void wxDebugMsg( const char *format, ... )
143 {
144 va_list ap;
145 va_start( ap, format );
146 vfprintf( stderr, format, ap );
147 fflush( stderr );
148 va_end(ap);
149 };
150
151 void wxError( const wxString &msg, const wxString &title )
152 {
153 fprintf( stderr, "Error " );
154 if (!title.IsNull()) fprintf( stderr, "%s ", WXSTRINGCAST(title) );
155 if (!msg.IsNull()) fprintf( stderr, ": %s", WXSTRINGCAST(msg) );
156 fprintf( stderr, ".\n" );
157 };
158
159 void wxFatalError( const wxString &msg, const wxString &title )
160 {
161 fprintf( stderr, "Error " );
162 if (!title.IsNull()) fprintf( stderr, "%s ", WXSTRINGCAST(title) );
163 if (!msg.IsNull()) fprintf( stderr, ": %s", WXSTRINGCAST(msg) );
164 fprintf( stderr, ".\n" );
165 exit(1);
166 };
167
168 //------------------------------------------------------------------------
169 // directory routines
170 //------------------------------------------------------------------------
171
172 bool wxDirExists( const wxString& dir )
173 {
174 char buf[500];
175 strcpy( buf, WXSTRINGCAST(dir) );
176 struct stat sbuf;
177 return ((stat(buf, &sbuf) != -1) && S_ISDIR(sbuf.st_mode) ? TRUE : FALSE);
178 };
179
180 //------------------------------------------------------------------------
181 // wild character routines
182 //------------------------------------------------------------------------
183
184 bool wxIsWild( const wxString& pattern )
185 {
186 wxString tmp = pattern;
187 char *pat = WXSTRINGCAST(tmp);
188 while (*pat) {
189 switch (*pat++) {
190 case '?': case '*': case '[': case '{':
191 return TRUE;
192 case '\\':
193 if (!*pat++)
194 return FALSE;
195 }
196 }
197 return FALSE;
198 };
199
200
201 bool wxMatchWild( const wxString& pat, const wxString& text, bool dot_special )
202 {
203 wxString tmp1 = pat;
204 char *pattern = WXSTRINGCAST(tmp1);
205 wxString tmp2 = text;
206 char *str = WXSTRINGCAST(tmp2);
207 char c;
208 char *cp;
209 bool done = FALSE, ret_code, ok;
210 // Below is for vi fans
211 const char OB = '{', CB = '}';
212
213 // dot_special means '.' only matches '.'
214 if (dot_special && *str == '.' && *pattern != *str)
215 return FALSE;
216
217 while ((*pattern != '\0') && (!done)
218 && (((*str=='\0')&&((*pattern==OB)||(*pattern=='*')))||(*str!='\0'))) {
219 switch (*pattern) {
220 case '\\':
221 pattern++;
222 if (*pattern != '\0')
223 pattern++;
224 break;
225 case '*':
226 pattern++;
227 ret_code = FALSE;
228 while ((*str!='\0')
229 && (!(ret_code=wxMatchWild(pattern, str++, FALSE))))
230 /*loop*/;
231 if (ret_code) {
232 while (*str != '\0')
233 str++;
234 while (*pattern != '\0')
235 pattern++;
236 }
237 break;
238 case '[':
239 pattern++;
240 repeat:
241 if ((*pattern == '\0') || (*pattern == ']')) {
242 done = TRUE;
243 break;
244 }
245 if (*pattern == '\\') {
246 pattern++;
247 if (*pattern == '\0') {
248 done = TRUE;
249 break;
250 }
251 }
252 if (*(pattern + 1) == '-') {
253 c = *pattern;
254 pattern += 2;
255 if (*pattern == ']') {
256 done = TRUE;
257 break;
258 }
259 if (*pattern == '\\') {
260 pattern++;
261 if (*pattern == '\0') {
262 done = TRUE;
263 break;
264 }
265 }
266 if ((*str < c) || (*str > *pattern)) {
267 pattern++;
268 goto repeat;
269 }
270 } else if (*pattern != *str) {
271 pattern++;
272 goto repeat;
273 }
274 pattern++;
275 while ((*pattern != ']') && (*pattern != '\0')) {
276 if ((*pattern == '\\') && (*(pattern + 1) != '\0'))
277 pattern++;
278 pattern++;
279 }
280 if (*pattern != '\0') {
281 pattern++, str++;
282 }
283 break;
284 case '?':
285 pattern++;
286 str++;
287 break;
288 case OB:
289 pattern++;
290 while ((*pattern != CB) && (*pattern != '\0')) {
291 cp = str;
292 ok = TRUE;
293 while (ok && (*cp != '\0') && (*pattern != '\0')
294 && (*pattern != ',') && (*pattern != CB)) {
295 if (*pattern == '\\')
296 pattern++;
297 ok = (*pattern++ == *cp++);
298 }
299 if (*pattern == '\0') {
300 ok = FALSE;
301 done = TRUE;
302 break;
303 } else if (ok) {
304 str = cp;
305 while ((*pattern != CB) && (*pattern != '\0')) {
306 if (*++pattern == '\\') {
307 if (*++pattern == CB)
308 pattern++;
309 }
310 }
311 } else {
312 while (*pattern!=CB && *pattern!=',' && *pattern!='\0') {
313 if (*++pattern == '\\') {
314 if (*++pattern == CB || *pattern == ',')
315 pattern++;
316 }
317 }
318 }
319 if (*pattern != '\0')
320 pattern++;
321 }
322 break;
323 default:
324 if (*str == *pattern) {
325 str++, pattern++;
326 } else {
327 done = TRUE;
328 }
329 }
330 }
331 while (*pattern == '*')
332 pattern++;
333 return ((*str == '\0') && (*pattern == '\0'));
334 };
335
336 //------------------------------------------------------------------------
337 // subprocess routines
338 //------------------------------------------------------------------------
339
340 long wxExecute( char **argv, bool Async )
341 {
342 if (*argv == NULL)
343 return FALSE;
344
345 /* fork the process */
346 #if defined(sun) || defined(__ultrix) || defined(__bsdi__)
347 pid_t pid = vfork();
348 #else
349 pid_t pid = fork();
350 #endif
351 if (pid == -1) {
352 perror ("fork failed");
353 return FALSE;
354 } else if (pid == 0) {
355 /* child */
356 #ifdef _AIX
357 execvp ((const char *)*argv, (const char **)argv);
358 #else
359 execvp (*argv, argv);
360 #endif
361 if (errno == ENOENT)
362 wxError("command not found", *argv);
363 else
364 perror (*argv);
365 wxError("could not execute", *argv);
366 _exit (-1);
367 }
368
369 // Code below is NOT really acceptable!
370 // One should NEVER use wait under X
371 // Ideas? A Sleep idle callback?
372 // WARNING: WARNING: WARNING: WARNING:
373 // The CODE BELOW IS BAD BAD BAD BAD!
374 if (Async) {
375 int status;
376 /*
377 wxSleep(2); // Give a little time
378 */
379 #if !defined(DG) && \
380 !defined(__AIX__) && \
381 !defined(__xlC__) && \
382 !defined(__SVR4__) && \
383 !defined(__SUN__) && \
384 !defined(__ALPHA__) && \
385 !defined(__SGI__) && \
386 !defined(__HPUX__) && \
387 !defined(__SUNPRO_CC) && \
388 !defined(__FreeBSD__)
389 while (wait((union wait*)&status) != pid)
390 #else
391 while (wait(&status) != pid)
392 #endif
393 {};
394 /*
395 wxSleep(3); // 3 sec?
396 */
397 };
398 return TRUE;
399 };
400
401 long wxExecute( const wxString& command, bool Async )
402 {
403 if (command.IsNull() || command == "") return FALSE;
404
405 int argc = 0;
406 char *argv[127];
407 char tmp[1024];
408 const char *IFS = " \t\n";
409
410 strncpy (tmp, command, sizeof(tmp) / sizeof(char) - 1);
411 tmp[sizeof (tmp) / sizeof (char) - 1] = '\0';
412 argv[argc++] = strtok (tmp, IFS);
413 while ((argv[argc++] = strtok(NULL, IFS)) != NULL)
414 /* loop */ ;
415 return wxExecute(argv, Async);
416 };
417