2 * Copyright 2001, 2002, 2003 David Mansfield and Cobite, Inc.
3 * See COPYING file for license information
13 #include <tsearch/search.h>
15 int setenv(const char *name
, const char *value
, int overwrite
);
16 void unsetenv(const char *name
);
26 #include <sys/types.h>
31 #include <cbtcommon/debug.h>
35 typedef int (*compare_func
)(const void *, const void *);
37 static void * string_tree
;
38 char *readfile(char const *filename
, char *buf
, size_t size
)
44 fp
= fopen(filename
, "r");
48 ptr
= fgets(buf
, size
, fp
);
55 if (buf
[len
-1] == '\n')
61 char *strrep(char *s
, char find
, char replace
)
77 static char prefix
[PATH_MAX
];
79 const char * home_env
;
85 home_env
= "APPDATA"; /* application data is below user's home dir */
90 if (!(home
= getenv(home_env
)))
92 debug(DEBUG_APPERROR
, "%s environment variable not set", home_env
);
96 if (snprintf(prefix
, PATH_MAX
, "%s/%s", home
, CVSPS_PREFIX
) >= PATH_MAX
)
98 debug(DEBUG_APPERROR
, "prefix buffer overflow");
102 /* Make sure the prefix directory exists */
103 if (stat(prefix
, &sbuf
) < 0)
109 ret
= mkdir(prefix
, 0777);
113 debug(DEBUG_SYSERROR
, "Cannot create the cvsps directory '%s'", CVSPS_PREFIX
);
119 if (!(S_ISDIR(sbuf
.st_mode
)))
120 debug(DEBUG_APPERROR
, "cvsps directory '%s' is not a directory!", CVSPS_PREFIX
);
126 char *xstrdup(char const *str
)
133 debug(DEBUG_ERROR
, "strdup failed");
140 void strzncpy(char * dst
, const char * src
, int n
)
142 strncpy(dst
, src
, n
);
146 char *get_string(char const *str
)
153 res
= (char **)tfind(str
, &string_tree
, (compare_func
)strcmp
);
156 char *key
= xstrdup(str
);
157 res
= (char **)tsearch(key
, &string_tree
, (compare_func
)strcmp
);
164 static int get_int_substr(const char * str
, const regmatch_t
* p
)
167 memcpy(buff
, str
+ p
->rm_so
, p
->rm_eo
- p
->rm_so
);
168 buff
[p
->rm_eo
- p
->rm_so
] = 0;
172 static time_t mktime_utc(struct tm
* tm
)
174 char * old_tz
= getenv("TZ");
177 setenv("TZ", "UTC", 1);
184 setenv("TZ", old_tz
, 1);
193 void convert_date(time_t * t
, const char * dte
)
195 static regex_t date_re
;
199 size_t nmatch
= MAX_MATCH
;
200 regmatch_t match
[MAX_MATCH
];
204 if (regcomp(&date_re
, "([0-9]{4})[-/]([0-9]{2})[-/]([0-9]{2}) ([0-9]{2}):([0-9]{2}):([0-9]{2})", REG_EXTENDED
))
206 fprintf(stderr
, "FATAL: date regex compilation error\n");
212 if (regexec(&date_re
, dte
, nmatch
, match
, 0) == 0)
214 regmatch_t
* pm
= match
;
217 /* first regmatch_t is match location of entire re */
220 tm
.tm_year
= get_int_substr(dte
, pm
++);
221 tm
.tm_mon
= get_int_substr(dte
, pm
++);
222 tm
.tm_mday
= get_int_substr(dte
, pm
++);
223 tm
.tm_hour
= get_int_substr(dte
, pm
++);
224 tm
.tm_min
= get_int_substr(dte
, pm
++);
225 tm
.tm_sec
= get_int_substr(dte
, pm
++);
230 *t
= mktime_utc(&tm
);
238 static struct timeval start_time
;
242 gettimeofday(&start_time
, NULL
);
245 void timing_stop(const char * msg
)
247 struct timeval stop_time
;
248 gettimeofday(&stop_time
, NULL
);
249 stop_time
.tv_sec
-= start_time
.tv_sec
;
250 stop_time
.tv_usec
-= start_time
.tv_usec
;
251 if (stop_time
.tv_usec
< 0)
252 stop_time
.tv_sec
--,stop_time
.tv_usec
+= 1000000;
254 printf("Elapsed time for %s: %d.%06d\n", msg
, (int)stop_time
.tv_sec
, (int)stop_time
.tv_usec
);
257 extern char ** environ
;
259 /* taken from the linux manual page for system
260 See http://linux.die.net/man/3/system
262 int my_system (const char *command
)
265 /* Launch child process */
267 ZeroMemory( &si
, sizeof( si
) );
268 si
.cb
= sizeof( si
);
269 PROCESS_INFORMATION pi
;
270 ZeroMemory( &pi
, sizeof( pi
) );
272 0, /* module name (0 means use first token in command line) */
273 (char*)command
, /* command line */
274 0, /* process security attributes */
275 0, /* primary thread security attributes */
276 TRUE
, /* handles are inherited */
277 0, /* creation flags (none) */
278 0, /* use parent's environment */
279 0, /* use parent's current directory */
280 &si
, /* STARTUPINFO pointer */
281 &pi
/* receives PROCESS_INFORMATION */
283 debug(DEBUG_APPERROR
, "CreateProcess failed.\n command line was: %s", command
);
287 /* Wait for child process to exit */
288 DWORD timeout
= 10*1000; /* milliseconds */
289 DWORD ret
= WaitForSingleObject( pi
.hProcess
, timeout
);
290 if (ret
== WAIT_OBJECT_0
) {
291 /* OK. Child has exited */
293 else if (ret
== WAIT_FAILED
) {
294 DWORD last_err
= GetLastError();
295 debug(DEBUG_APPERROR
, "WaitForSingleObject failed.\n GetLastError returned : %d", last_err
);
299 debug(DEBUG_APPERROR
, "WaitForSingleObject returned %x", ret
);
303 /* Retrieve exit code */
305 if( !GetExitCodeProcess( pi
.hProcess
, &exit_code
) ) {
306 DWORD last_err
= GetLastError();
307 debug(DEBUG_APPERROR
, "GetExitCodeProcess failed.\n GetLastError returned : %d", last_err
);
324 argv
[2] = (char*)command
; /* discard const */
326 execve("/bin/sh", argv
, environ
);
330 if (waitpid(pid
, &status
, 0) == -1) {
339 int escape_filename(char * dst
, int len
, const char * src
)
341 static char * naughty_chars
= " \\\"'@<>=;|&()#$`?*[!:{";
345 while (len
> 1 && *src
)
347 if (strchr(naughty_chars
, *src
))
362 return (*src
== 0) ? 0 : -1;