Import KDE4.3.1 from wip
[pkgsrc.git] / bootstrap / bmake / util.c
1 /*      $NetBSD: util.c,v 1.2 2004/01/14 11:20:30 grant Exp $   */
2
3 /*
4  * Missing stuff from OS's
5  *
6  *      $Id: util.c,v 1.1.1.1 2004/03/11 13:04:13 grant Exp $
7  */
8
9 #ifdef MAKE_BOOTSTRAP
10 static char rcsid[] = "$NetBSD: util.c,v 1.2 2004/01/14 11:20:30 grant Exp $";
11 #else
12 #include <sys/cdefs.h>
13 #ifndef lint
14 __RCSID("$NetBSD: util.c,v 1.2 2004/01/14 11:20:30 grant Exp $");
15 #endif
16 #endif
17
18 #include <stdio.h>
19 #include <time.h>
20 #include "make.h"
21 #include <sys/param.h>
22 #ifdef HAVE_STRING_H
23 #include <string.h>
24 #endif
25
26 #ifndef __STDC__
27 # ifndef const
28 #  define const
29 # endif
30 #endif
31
32 #if !defined(HAVE_STRERROR)
33
34 extern int errno, sys_nerr;
35 extern char *sys_errlist[];
36
37 char *
38 strerror(e)
39     int e;
40 {
41     static char buf[100];
42     if (e < 0 || e >= sys_nerr) {
43         snprintf(buf, sizeof(buf), "Unknown error %d", e);
44         return buf;
45     }
46     else
47         return sys_errlist[e];
48 }
49 #endif
50
51 #if !defined(HAVE_STRDUP)
52 /* strdup
53  *
54  * Make a duplicate of a string.
55  * For systems which lack this function.
56  */
57 char *
58 strdup(str)
59     const char *str;
60 {
61     size_t len;
62     char *p;
63
64     if (str == NULL)
65         return NULL;
66     len = strlen(str) + 1;
67     p = emalloc(len);
68
69     return memcpy(p, str, len);
70 }
71
72 #endif
73
74 #if !defined(HAVE_SETENV)
75 int
76 setenv(name, value, dum)
77     const char *name;
78     const char *value;
79     int dum;
80 {
81     register char *p;
82     int len = strlen(name) + strlen(value) + 2; /* = \0 */
83     char *ptr = (char*) emalloc(len);
84
85     (void) dum;
86
87     if (ptr == NULL)
88         return -1;
89
90     p = ptr;
91
92     while (*name)
93         *p++ = *name++;
94
95     *p++ = '=';
96
97     while (*value)
98         *p++ = *value++;
99
100     *p = '\0';
101
102     len = putenv(ptr);
103 /*    free(ptr); */
104     return len;
105 }
106 #endif
107
108 #if defined(__hpux) && !defined(_HPUX_SOURCE)
109 #include <sys/types.h>
110 #include <sys/param.h>
111 #include <sys/syscall.h>
112 #include <sys/signal.h>
113 #include <sys/stat.h>
114 #include <stdio.h>
115 #include <dirent.h>
116 #include <sys/time.h>
117 #include <time.h>
118 #include <unistd.h>
119
120
121 int
122 killpg(pid, sig)
123     int pid, sig;
124 {
125     return kill(-pid, sig);
126 }
127
128 void
129 srandom(seed)
130     long seed;
131 {
132     srand48(seed);
133 }
134
135 long
136 random()
137 {
138     return lrand48();
139 }
140
141 int
142 setpriority(which, who, niceval)
143    int which, who, niceval;
144 {
145 #ifdef SYS_setpriority
146    return syscall(SYS_setpriority, which, who, niceval);
147 #else
148 #ifndef ENOSYS
149 # define ENOSYS 90
150 #endif
151    extern int errno;
152    errno = ENOSYS;
153    return -1;
154 #endif
155 }
156
157 int
158 setreuid(euid, ruid)
159    int euid, ruid;
160 {
161    return setresuid(euid, ruid, -1);
162 }
163     
164 int
165 setregid(egid, rgid)
166    int egid, rgid;
167 {
168    return setresgid(egid, rgid, -1);
169 }
170 #endif /* __hpux && !_HPUX_SOURCE */
171
172 #if defined(__hpux__) || defined(__hpux)
173
174 /* strrcpy():
175  *      Like strcpy, going backwards and returning the new pointer
176  */
177 static char *
178 strrcpy(ptr, str)
179     register char *ptr, *str;
180 {
181     register int len = strlen(str);
182
183     while (len)
184         *--ptr = str[--len];
185
186     return (ptr);
187 } /* end strrcpy */
188
189
190 char    *sys_siglist[] = {
191         "Signal 0",
192         "Hangup",                       /* SIGHUP    */
193         "Interrupt",                    /* SIGINT    */
194         "Quit",                         /* SIGQUIT   */
195         "Illegal instruction",          /* SIGILL    */
196         "Trace/BPT trap",               /* SIGTRAP   */
197         "IOT trap",                     /* SIGIOT    */
198         "EMT trap",                     /* SIGEMT    */
199         "Floating point exception",     /* SIGFPE    */
200         "Killed",                       /* SIGKILL   */
201         "Bus error",                    /* SIGBUS    */
202         "Segmentation fault",           /* SIGSEGV   */
203         "Bad system call",              /* SIGSYS    */
204         "Broken pipe",                  /* SIGPIPE   */
205         "Alarm clock",                  /* SIGALRM   */
206         "Terminated",                   /* SIGTERM   */
207         "User defined signal 1",        /* SIGUSR1   */
208         "User defined signal 2",        /* SIGUSR2   */
209         "Child exited",                 /* SIGCLD    */
210         "Power-fail restart",           /* SIGPWR    */
211         "Virtual timer expired",        /* SIGVTALRM */
212         "Profiling timer expired",      /* SIGPROF   */
213         "I/O possible",                 /* SIGIO     */
214         "Window size changes",          /* SIGWINDOW */
215         "Stopped (signal)",             /* SIGSTOP   */
216         "Stopped",                      /* SIGTSTP   */
217         "Continued",                    /* SIGCONT   */
218         "Stopped (tty input)",          /* SIGTTIN   */
219         "Stopped (tty output)",         /* SIGTTOU   */
220         "Urgent I/O condition",         /* SIGURG    */
221         "Remote lock lost (NFS)",       /* SIGLOST   */
222         "Signal 31",                    /* reserved  */
223         "DIL signal"                    /* SIGDIL    */
224 };
225 #endif /* __hpux__ || __hpux */
226
227 #if defined(__hpux) && !defined(_HPUX_SOURCE)
228
229 int
230 utimes(file, tvp)
231     char *file;
232     struct timeval tvp[2];
233 {
234     struct utimbuf t;
235
236     t.actime  = tvp[0].tv_sec;
237     t.modtime = tvp[1].tv_sec;
238     return(utime(file, &t));
239 }
240
241 #if !defined(BSD) && !defined(d_fileno)
242 # define d_fileno d_ino
243 #endif
244
245 #ifndef DEV_DEV_COMPARE
246 # define DEV_DEV_COMPARE(a, b) ((a) == (b))
247 #endif
248 #define ISDOT(c) ((c)[0] == '.' && (((c)[1] == '\0') || ((c)[1] == '/')))
249 #define ISDOTDOT(c) ((c)[0] == '.' && ISDOT(&((c)[1])))
250
251 char   *
252 getwd(pathname)
253     char   *pathname;
254 {
255     DIR    *dp;
256     struct dirent *d;
257     extern int errno;
258
259     struct stat st_root, st_cur, st_next, st_dotdot;
260     char    pathbuf[MAXPATHLEN], nextpathbuf[MAXPATHLEN * 2];
261     char   *pathptr, *nextpathptr, *cur_name_add;
262
263     /* find the inode of root */
264     if (stat("/", &st_root) == -1) {
265         (void) snprintf(pathname, sizeof(pathname),
266                         "getwd: Cannot stat \"/\" (%s)", strerror(errno));
267         return (NULL);
268     }
269     pathbuf[MAXPATHLEN - 1] = '\0';
270     pathptr = &pathbuf[MAXPATHLEN - 1];
271     nextpathbuf[MAXPATHLEN - 1] = '\0';
272     cur_name_add = nextpathptr = &nextpathbuf[MAXPATHLEN - 1];
273
274     /* find the inode of the current directory */
275     if (lstat(".", &st_cur) == -1) {
276         (void) snprintf(pathname, sizeof(pathname),
277                         "getwd: Cannot stat \".\" (%s)", strerror(errno));
278         return (NULL);
279     }
280     nextpathptr = strrcpy(nextpathptr, "../");
281
282     /* Descend to root */
283     for (;;) {
284
285         /* look if we found root yet */
286         if (st_cur.st_ino == st_root.st_ino &&
287             DEV_DEV_COMPARE(st_cur.st_dev, st_root.st_dev)) {
288             (void) strcpy(pathname, *pathptr != '/' ? "/" : pathptr);
289             return (pathname);
290         }
291
292         /* open the parent directory */
293         if (stat(nextpathptr, &st_dotdot) == -1) {
294             (void) snprintf(pathname, sizeof(pathname),
295                             "getwd: Cannot stat directory \"%s\" (%s)",
296                             nextpathptr, strerror(errno));
297             return (NULL);
298         }
299         if ((dp = opendir(nextpathptr)) == NULL) {
300             (void) snprintf(pathname, sizeof(pathname),
301                             "getwd: Cannot open directory \"%s\" (%s)",
302                             nextpathptr, strerror(errno));
303             return (NULL);
304         }
305
306         /* look in the parent for the entry with the same inode */
307         if (DEV_DEV_COMPARE(st_dotdot.st_dev, st_cur.st_dev)) {
308             /* Parent has same device. No need to stat every member */
309             for (d = readdir(dp); d != NULL; d = readdir(dp))
310                 if (d->d_fileno == st_cur.st_ino)
311                     break;
312         }
313         else {
314             /*
315              * Parent has a different device. This is a mount point so we
316              * need to stat every member
317              */
318             for (d = readdir(dp); d != NULL; d = readdir(dp)) {
319                 if (ISDOT(d->d_name) || ISDOTDOT(d->d_name))
320                     continue;
321                 (void) strcpy(cur_name_add, d->d_name);
322                 if (lstat(nextpathptr, &st_next) == -1) {
323                     (void) snprintf(pathname, sizeof(pathname),
324                         "getwd: Cannot stat \"%s\" (%s)",
325                         d->d_name, strerror(errno));
326                     (void) closedir(dp);
327                     return (NULL);
328                 }
329                 /* check if we found it yet */
330                 if (st_next.st_ino == st_cur.st_ino &&
331                     DEV_DEV_COMPARE(st_next.st_dev, st_cur.st_dev))
332                     break;
333             }
334         }
335         if (d == NULL) {
336             (void) snprintf(pathname, sizeof(pathname), 
337                 "getwd: Cannot find \".\" in \"..\"");
338             (void) closedir(dp);
339             return (NULL);
340         }
341         st_cur = st_dotdot;
342         pathptr = strrcpy(pathptr, d->d_name);
343         pathptr = strrcpy(pathptr, "/");
344         nextpathptr = strrcpy(nextpathptr, "../");
345         (void) closedir(dp);
346         *cur_name_add = '\0';
347     }
348 } /* end getwd */
349
350 #endif /* __hpux && !_HPUX_SOURCE */
351
352 #if !defined(HAVE_GETCWD)
353 char *
354 getcwd(path, sz)
355      char *path;
356      int sz;
357 {
358         return getwd(path);
359 }
360 #endif
361
362
363 #if !defined(HAVE_VSNPRINTF)
364 #if !defined(BSD4_4) && !defined(SUNOS_5_7) && !defined(__linux__)
365 #ifdef __STDC__
366 #include <stdarg.h>
367 #else
368 #include <varargs.h>
369 #endif
370
371 #if !defined(__osf__)
372 #ifdef _IOSTRG
373 #define STRFLAG (_IOSTRG|_IOWRT)        /* no _IOWRT: avoid stdio bug */
374 #else
375 #if 0
376 #define STRFLAG (_IOREAD)               /* XXX: Assume svr4 stdio */
377 #endif
378 #endif /* _IOSTRG */
379 #endif /* __osf__ */
380
381 int
382 vsnprintf(s, n, fmt, args)
383         char *s;
384         size_t n;
385         const char *fmt;
386         va_list args;
387 {
388 #ifdef STRFLAG
389         FILE fakebuf;
390
391         fakebuf._flag = STRFLAG;
392         /*
393          * Some os's are char * _ptr, others are unsigned char *_ptr...
394          * We cast to void * to make everyone happy.
395          */
396         fakebuf._ptr = (void *) s;
397         fakebuf._cnt = n-1;
398         fakebuf._file = -1;
399         _doprnt(fmt, args, &fakebuf);
400         fakebuf._cnt++;
401         putc('\0', &fakebuf);
402         if (fakebuf._cnt<0)
403             fakebuf._cnt = 0;
404         return (n-fakebuf._cnt-1);
405 #else
406         (void) vsprintf(s, fmt, args);
407         return strlen(s);
408 #endif
409 }
410 #endif
411 #endif
412
413 #if !defined(HAVE_SNPRINTF)
414 int
415 #ifdef __STDC__
416 snprintf(char *s, size_t n, const char *fmt, ...)
417 #else
418 snprintf(va_alist)
419         va_dcl
420 #endif
421 {
422         va_list ap;
423         int rv;
424 #ifdef __STDC__
425         va_start(ap, fmt);
426 #else
427         char *s;
428         size_t n;
429         const char *fmt;
430
431         va_start(ap);
432
433         s = va_arg(ap, char *);
434         n = va_arg(ap, size_t);
435         fmt = va_arg(ap, const char *);
436 #endif
437         rv = vsnprintf(s, n, fmt, ap);
438         va_end(ap);
439         return rv;
440 }
441 #endif
442
443 #if !defined(HAVE_STRFTIME)
444 int
445 strftime(buf, len, fmt, tm)
446         char *buf;
447         size_t len;
448         const char *fmt;
449         const struct tm *tm;
450 {
451         static char months[][4] = {
452                 "Jan", "Feb", "Mar", "Apr", "May", "Jun", 
453                 "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
454         };
455
456         size_t s;
457         char *b = buf;
458
459         while (*fmt) {
460                 if (len == 0)
461                         return buf - b;
462                 if (*fmt != '%') {
463                         *buf++ = *fmt++;
464                         len--;
465                         continue;
466                 }
467                 switch (*fmt++) {
468                 case '%':
469                         *buf++ = '%';
470                         len--;
471                         if (len == 0) return buf - b;
472                         /*FALLTHROUGH*/
473                 case '\0':
474                         *buf = '%';
475                         s = 1;
476                         break;
477                 case 'k':
478                         s = snprintf(buf, len, "%d", tm->tm_hour);
479                         break;
480                 case 'M':
481                         s = snprintf(buf, len, "%02d", tm->tm_min);
482                         break;
483                 case 'S':
484                         s = snprintf(buf, len, "%02d", tm->tm_sec);
485                         break;
486                 case 'b':
487                         if (tm->tm_mon >= 12)
488                                 return buf - b;
489                         s = snprintf(buf, len, "%s", months[tm->tm_mon]);
490                         break;
491                 case 'd':
492                         s = snprintf(buf, len, "%s", tm->tm_mday);
493                         break;
494                 case 'Y':
495                         s = snprintf(buf, len, "%s", 1900 + tm->tm_year);
496                         break;
497                 default:
498                         s = snprintf(buf, len, "Unsupported format %c",
499                             fmt[-1]);
500                         break;
501                 }
502                 buf += s;
503                 len -= s;
504         }
505 }
506 #endif