1 /* $RCSfile: util.c,v $$Revision: 4.0.1.2 $$Date: 91/06/07 12:10:42 $
3 * Copyright (c) 1991, Larry Wall
5 * You may distribute under the terms of either the GNU General Public
6 * License or the Artistic License, as specified in the README file.
9 * Revision 4.0.1.2 91/06/07 12:10:42 lwall
10 * patch4: new copyright notice
11 * patch4: made some allowances for "semi-standard" C
12 * patch4: index() could blow up searching for null string
13 * patch4: taintchecks could improperly modify parent in vfork()
14 * patch4: exec would close files even if you cleared close-on-exec flag
16 * Revision 4.0.1.1 91/04/12 09:19:25 lwall
17 * patch1: random cleanup in cpp namespace
19 * Revision 4.0 91/03/20 01:56:39 lwall
27 #if !defined(NSIG) || defined(M_UNIX) || defined(M_XENIX)
43 # include <sys/file.h>
48 static char nomem[] = "Out of memory!\n";
50 /* paranoid version of malloc */
56 /* NOTE: Do not call the next three routines directly. Use the macros
57 * in handy.h, so that we can easily redefine everything to do tracking of
58 * allocated hunks back to the original New to track down any memory leaks.
72 #endif /* ! STANDARD_C */
76 fprintf(stderr, "Allocation too large: %lx\n", size) FLUSH;
82 fatal("panic: malloc");
84 ptr = malloc(size?size:1); /* malloc(0) is NASTY on our system */
88 fprintf(stderr,"0x%x: (%05d) malloc %d bytes\n",ptr,an++,size);
91 fprintf(stderr,"0x%lx: (%05d) malloc %d bytes\n",ptr,an++,size);
97 fputs(nomem,stderr) FLUSH;
106 /* paranoid version of realloc */
109 saferealloc(where,size)
120 #endif /* ! STANDARD_C */
124 fprintf(stderr, "Reallocation too large: %lx\n", size) FLUSH;
129 fatal("Null realloc");
132 fatal("panic: realloc");
134 ptr = realloc(where,size?size:1); /* realloc(0) is NASTY on our system */
138 fprintf(stderr,"0x%x: (%05d) rfree\n",where,an++);
139 fprintf(stderr,"0x%x: (%05d) realloc %d bytes\n",ptr,an++,size);
143 fprintf(stderr,"0x%lx: (%05d) rfree\n",where,an++);
144 fprintf(stderr,"0x%lx: (%05d) realloc %d bytes\n",ptr,an++,size);
151 fputs(nomem,stderr) FLUSH;
160 /* safe version of free */
169 fprintf(stderr,"0x%x: (%05d) free\n",where,an++);
172 fprintf(stderr,"0x%lx: (%05d) free\n",where,an++);
182 #define ALIGN sizeof(long)
189 register char *where;
191 where = safemalloc(size + ALIGN);
195 return where + ALIGN;
199 safexrealloc(where,size)
203 return saferealloc(where - ALIGN, size + ALIGN) + ALIGN;
215 x = where[0] + 100 * where[1];
224 for (i = 0; i < MAXXCOUNT; i++) {
225 if (xcount[i] != lastxcount[i]) {
226 fprintf(stderr,"%2d %2d\t%ld\n", i / 100, i % 100, xcount[i]);
227 lastxcount[i] = xcount[i];
232 #endif /* LEAKTEST */
234 /* copy a string up to some (non-backslashed) delimiter, if any */
237 cpytill(to,from,fromend,delim,retlen)
240 register char *fromend;
246 for (; from < fromend; from++,to++) {
248 if (from[1] == delim)
250 else if (from[1] == '\\')
253 else if (*from == delim)
258 *retlen = to - origto;
262 /* return ptr to little string in big string, NULL if not found */
263 /* This routine was donated by Corey Satten. */
268 register char *little;
270 register char *s, *x;
281 for (x=big,s=little; *s; /**/ ) {
295 /* same as instr but allow embedded nulls */
298 ninstr(big, bigend, little, lend)
300 register char *bigend;
304 register char *s, *x;
305 register int first = *little;
306 register char *littleend = lend;
308 if (!first && little > littleend)
310 bigend -= littleend - little++;
311 while (big <= bigend) {
314 for (x=big,s=little; s < littleend; /**/ ) {
326 /* reverse of the above--find last substring */
329 rninstr(big, bigend, little, lend)
335 register char *bigbeg;
336 register char *s, *x;
337 register int first = *little;
338 register char *littleend = lend;
340 if (!first && little > littleend)
343 big = bigend - (littleend - little++);
344 while (big >= bigbeg) {
347 for (x=big+2,s=little; s < littleend; /**/ ) {
359 unsigned char fold[] = {
360 0, 1, 2, 3, 4, 5, 6, 7,
361 8, 9, 10, 11, 12, 13, 14, 15,
362 16, 17, 18, 19, 20, 21, 22, 23,
363 24, 25, 26, 27, 28, 29, 30, 31,
364 32, 33, 34, 35, 36, 37, 38, 39,
365 40, 41, 42, 43, 44, 45, 46, 47,
366 48, 49, 50, 51, 52, 53, 54, 55,
367 56, 57, 58, 59, 60, 61, 62, 63,
368 64, 'a', 'b', 'c', 'd', 'e', 'f', 'g',
369 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o',
370 'p', 'q', 'r', 's', 't', 'u', 'v', 'w',
371 'x', 'y', 'z', 91, 92, 93, 94, 95,
372 96, 'A', 'B', 'C', 'D', 'E', 'F', 'G',
373 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O',
374 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W',
375 'X', 'Y', 'Z', 123, 124, 125, 126, 127,
376 128, 129, 130, 131, 132, 133, 134, 135,
377 136, 137, 138, 139, 140, 141, 142, 143,
378 144, 145, 146, 147, 148, 149, 150, 151,
379 152, 153, 154, 155, 156, 157, 158, 159,
380 160, 161, 162, 163, 164, 165, 166, 167,
381 168, 169, 170, 171, 172, 173, 174, 175,
382 176, 177, 178, 179, 180, 181, 182, 183,
383 184, 185, 186, 187, 188, 189, 190, 191,
384 192, 193, 194, 195, 196, 197, 198, 199,
385 200, 201, 202, 203, 204, 205, 206, 207,
386 208, 209, 210, 211, 212, 213, 214, 215,
387 216, 217, 218, 219, 220, 221, 222, 223,
388 224, 225, 226, 227, 228, 229, 230, 231,
389 232, 233, 234, 235, 236, 237, 238, 239,
390 240, 241, 242, 243, 244, 245, 246, 247,
391 248, 249, 250, 251, 252, 253, 254, 255
394 static unsigned char freq[] = {
395 1, 2, 84, 151, 154, 155, 156, 157,
396 165, 246, 250, 3, 158, 7, 18, 29,
397 40, 51, 62, 73, 85, 96, 107, 118,
398 129, 140, 147, 148, 149, 150, 152, 153,
399 255, 182, 224, 205, 174, 176, 180, 217,
400 233, 232, 236, 187, 235, 228, 234, 226,
401 222, 219, 211, 195, 188, 193, 185, 184,
402 191, 183, 201, 229, 181, 220, 194, 162,
403 163, 208, 186, 202, 200, 218, 198, 179,
404 178, 214, 166, 170, 207, 199, 209, 206,
405 204, 160, 212, 216, 215, 192, 175, 173,
406 243, 172, 161, 190, 203, 189, 164, 230,
407 167, 248, 227, 244, 242, 255, 241, 231,
408 240, 253, 169, 210, 245, 237, 249, 247,
409 239, 168, 252, 251, 254, 238, 223, 221,
410 213, 225, 177, 197, 171, 196, 159, 4,
411 5, 6, 8, 9, 10, 11, 12, 13,
412 14, 15, 16, 17, 19, 20, 21, 22,
413 23, 24, 25, 26, 27, 28, 30, 31,
414 32, 33, 34, 35, 36, 37, 38, 39,
415 41, 42, 43, 44, 45, 46, 47, 48,
416 49, 50, 52, 53, 54, 55, 56, 57,
417 58, 59, 60, 61, 63, 64, 65, 66,
418 67, 68, 69, 70, 71, 72, 74, 75,
419 76, 77, 78, 79, 80, 81, 82, 83,
420 86, 87, 88, 89, 90, 91, 92, 93,
421 94, 95, 97, 98, 99, 100, 101, 102,
422 103, 104, 105, 106, 108, 109, 110, 111,
423 112, 113, 114, 115, 116, 117, 119, 120,
424 121, 122, 123, 124, 125, 126, 127, 128,
425 130, 131, 132, 133, 134, 135, 136, 137,
426 138, 139, 141, 142, 143, 144, 145, 146
430 fbmcompile(str, iflag)
434 register unsigned char *s;
435 register unsigned char *table;
437 register int len = str->str_cur;
439 unsigned int frequency = 256;
441 Str_Grow(str,len+258);
443 table = (unsigned char*)(str->str_ptr + len + 1);
445 table = Null(unsigned char*);
448 for (i = 0; i < 256; i++) {
453 while (s >= (unsigned char*)(str->str_ptr))
456 if (table[*s] == len) {
459 table[*s] = table[fold[*s]] = i;
473 str->str_pok |= SP_FBM; /* deep magic */
476 s = (unsigned char*)(str->str_ptr); /* deeper magic */
478 s = Null(unsigned char*);
481 register unsigned int tmp, foldtmp;
482 str->str_pok |= SP_CASEFOLD;
483 for (i = 0; i < len; i++) {
485 foldtmp=freq[fold[s[i]]];
486 if (tmp < frequency && foldtmp < frequency) {
488 /* choose most frequent among the two */
489 frequency = (tmp > foldtmp) ? tmp : foldtmp;
494 for (i = 0; i < len; i++) {
495 if (freq[s[i]] < frequency) {
497 frequency = freq[s[i]];
501 str->str_rare = s[rarest];
502 str->str_state = rarest;
505 fprintf(stderr,"rarest char %c at %d\n",str->str_rare, str->str_state);
510 fbminstr(big, bigend, littlestr)
512 register unsigned char *bigend;
515 register unsigned char *s;
517 register int littlelen;
518 register unsigned char *little;
519 register unsigned char *table;
520 register unsigned char *olds;
521 register unsigned char *oldlittle;
524 if (!(littlestr->str_pok & SP_FBM)) {
525 if (!littlestr->str_ptr)
527 return ninstr((char*)big,(char*)bigend,
528 littlestr->str_ptr, littlestr->str_ptr + littlestr->str_cur);
532 littlelen = littlestr->str_cur;
534 if (littlestr->str_pok & SP_TAIL && !multiline) { /* tail anchored? */
535 if (littlelen > bigend - big)
537 little = (unsigned char*)littlestr->str_ptr;
538 if (littlestr->str_pok & SP_CASEFOLD) { /* oops, fake it */
539 big = bigend - littlelen; /* just start near end */
540 if (bigend[-1] == '\n' && little[littlelen-1] != '\n')
544 s = bigend - littlelen;
545 if (*s == *little && bcmp(s,little,littlelen)==0)
546 return (char*)s; /* how sweet it is */
547 else if (bigend[-1] == '\n' && little[littlelen-1] != '\n'
550 if (*s == *little && bcmp(s,little,littlelen)==0)
556 table = (unsigned char*)(littlestr->str_ptr + littlelen + 1);
558 table = Null(unsigned char*);
560 if (--littlelen >= bigend - big)
563 oldlittle = little = table - 2;
564 if (littlestr->str_pok & SP_CASEFOLD) { /* case insensitive? */
567 if (tmp = table[*s]) {
569 if (bigend - s > tmp) {
574 if ((s += tmp) < bigend)
580 tmp = littlelen; /* less expensive than calling strncmp() */
583 if (*--s == *--little || fold[*s] == *little)
585 s = olds + 1; /* here we pay the price for failure */
587 if (s < bigend) /* fake up continue to outer loop */
600 if (tmp = table[*s]) {
602 if (bigend - s > tmp) {
607 if ((s += tmp) < bigend)
613 tmp = littlelen; /* less expensive than calling strncmp() */
616 if (*--s == *--little)
618 s = olds + 1; /* here we pay the price for failure */
620 if (s < bigend) /* fake up continue to outer loop */
634 screaminstr(bigstr, littlestr)
638 register unsigned char *s, *x;
639 register unsigned char *big;
641 register int previous;
643 register unsigned char *little;
644 register unsigned char *bigend;
645 register unsigned char *littleend;
647 if ((pos = screamfirst[littlestr->str_rare]) < 0)
650 little = (unsigned char *)(littlestr->str_ptr);
652 little = Null(unsigned char *);
654 littleend = little + littlestr->str_cur;
656 previous = littlestr->str_state;
658 big = (unsigned char *)(bigstr->str_ptr);
660 big = Null(unsigned char*);
662 bigend = big + bigstr->str_cur;
664 while (pos < previous) {
666 if (!(pos += screamnext[pos]))
670 if (littlestr->str_pok & SP_CASEFOLD) { /* case insignificant? */
672 if (big[pos] != first && big[pos] != fold[first])
674 for (x=big+pos+1,s=little; s < littleend; /**/ ) {
677 if (*s++ != *x++ && fold[*(s-1)] != *(x-1)) {
684 return (char *)(big+pos);
690 pos += screamnext[pos] /* does this goof up anywhere? */
698 if (big[pos] != first)
700 for (x=big+pos+1,s=little; s < littleend; /**/ ) {
710 return (char *)(big+pos);
716 pos += screamnext[pos]
725 /* copy a string to a safe spot */
731 register char *newaddr;
733 New(902,newaddr,strlen(str)+1,char);
734 (void)strcpy(newaddr,str);
738 /* same thing but with a known length */
745 register char *newaddr;
747 New(903,newaddr,len+1,char);
748 (void)bcopy(str,newaddr,len); /* might not be null terminated */
749 newaddr[len] = '\0'; /* is now */
753 /* grow a static string to at least a certain length */
756 growstr(strptr,curlen,newlen)
761 if (newlen > *curlen) { /* need more room? */
763 Renew(*strptr,newlen,char);
765 New(905,*strptr,newlen,char);
772 mess(pat,a1,a2,a3,a4)
779 (void)sprintf(s,pat,a1,a2,a3,a4);
782 if (curcmd->c_line) {
783 (void)sprintf(s," at %s line %ld",
784 stab_val(curcmd->c_filestab)->str_ptr, (long)curcmd->c_line);
788 stab_io(last_in_stab) &&
789 stab_io(last_in_stab)->lines ) {
790 (void)sprintf(s,", <%s> line %ld",
791 last_in_stab == argvstab ? "" : stab_name(last_in_stab),
792 (long)stab_io(last_in_stab)->lines);
795 (void)strcpy(s,".\n");
800 fatal(pat,a1,a2,a3,a4)
805 extern char *e_tmpname;
808 mess(pat,a1,a2,a3,a4);
810 str_set(stab_val(stabent("@",TRUE)),buf);
812 while (loop_ptr >= 0 && (!loop_stack[loop_ptr].loop_label ||
813 strNE(tmps,loop_stack[loop_ptr].loop_label) )) {
816 deb("(Skipping label #%d %s)\n",loop_ptr,
817 loop_stack[loop_ptr].loop_label);
824 deb("(Found label #%d %s)\n",loop_ptr,
825 loop_stack[loop_ptr].loop_label);
830 fatal("Bad label: %s", tmps);
832 longjmp(loop_stack[loop_ptr].loop_env, 1);
835 (void)fflush(stderr);
837 (void)UNLINK(e_tmpname);
839 exit((int)((errno&255)?errno:((statusvalue&255)?statusvalue:255)));
843 warn(pat,a1,a2,a3,a4)
847 mess(pat,a1,a2,a3,a4);
855 (void)fflush(stderr);
876 pat = va_arg(args, char *);
878 (void) vsprintf(s,pat,args);
882 if (curcmd->c_line) {
883 (void)sprintf(s," at %s line %ld",
884 stab_val(curcmd->c_filestab)->str_ptr, (long)curcmd->c_line);
888 stab_io(last_in_stab) &&
889 stab_io(last_in_stab)->lines ) {
890 (void)sprintf(s,", <%s> line %ld",
891 last_in_stab == argvstab ? "" : last_in_stab->str_magic->str_ptr,
892 (long)stab_io(last_in_stab)->lines);
895 (void)strcpy(s,".\n");
905 extern char *e_tmpname;
916 str_set(stab_val(stabent("@",TRUE)),buf);
918 while (loop_ptr >= 0 && (!loop_stack[loop_ptr].loop_label ||
919 strNE(tmps,loop_stack[loop_ptr].loop_label) )) {
922 deb("(Skipping label #%d %s)\n",loop_ptr,
923 loop_stack[loop_ptr].loop_label);
930 deb("(Found label #%d %s)\n",loop_ptr,
931 loop_stack[loop_ptr].loop_label);
936 fatal("Bad label: %s", tmps);
938 longjmp(loop_stack[loop_ptr].loop_env, 1);
941 (void)fflush(stderr);
943 (void)UNLINK(e_tmpname);
945 exit((int)((errno&255)?errno:((statusvalue&255)?statusvalue:255)));
969 (void)fflush(stderr);
977 register int i=envix(nam); /* where does it go? */
979 if (environ == origenviron) { /* need we copy environment? */
984 for (max = i; environ[max]; max++) ;
985 New(901,tmpenv, max+2, char*);
986 for (j=0; j<max; j++) /* copy environment */
987 tmpenv[j] = savestr(environ[j]);
988 tmpenv[max] = Nullch;
989 environ = tmpenv; /* tell exec where it is now */
993 environ[i] = environ[i+1];
998 if (!environ[i]) { /* does not exist yet */
999 Renew(environ, i+2, char*); /* just expand it a bit */
1000 environ[i+1] = Nullch; /* make sure it's null terminated */
1003 Safefree(environ[i]);
1004 New(904, environ[i], strlen(nam) + strlen(val) + 2, char);
1006 (void)sprintf(environ[i],"%s=%s",nam,val);/* all that work just for this */
1008 /* MS-DOS requires environment variable names to be in uppercase */
1009 /* [Tom Dinger, 27 August 1990: Well, it doesn't _require_ it, but
1010 * some utilities and applications may break because they only look
1011 * for upper case strings. (Fixed strupr() bug here.)]
1013 strcpy(environ[i],nam); strupr(environ[i]);
1014 (void)sprintf(environ[i] + strlen(nam),"=%s",val);
1022 register int i, len = strlen(nam);
1024 for (i = 0; environ[i]; i++) {
1025 if (strnEQ(environ[i],nam,len) && environ[i][len] == '=')
1026 break; /* strnEQ must come first to avoid */
1027 } /* potential SEGV's */
1032 unlnk(f) /* unlink all versions of a file */
1037 for (i = 0; unlink(f) >= 0; i++) ;
1046 register char *from;
1081 vsprintf(dest, pat, args)
1082 char *dest, *pat, *args;
1086 fakebuf._ptr = dest;
1087 fakebuf._cnt = 32767;
1091 fakebuf._flag = _IOWRT|_IOSTRG;
1092 _doprnt(pat, args, &fakebuf); /* what a kludge */
1093 (void)putc('\0', &fakebuf);
1097 return 0; /* perl doesn't use return value */
1103 vfprintf(fd, pat, args)
1107 _doprnt(pat, args, fd);
1108 return 0; /* wrong, but perl doesn't use the return value */
1111 #endif /* HAS_VPRINTF */
1112 #endif /* I_VARARGS */
1115 #if BYTEORDER != 0x4321
1120 #if (BYTEORDER & 1) == 0
1123 result = ((s & 255) << 8) + ((s >> 8) & 255);
1136 char c[sizeof(long)];
1139 #if BYTEORDER == 0x1234
1140 u.c[0] = (l >> 24) & 255;
1141 u.c[1] = (l >> 16) & 255;
1142 u.c[2] = (l >> 8) & 255;
1146 #if ((BYTEORDER - 0x1111) & 0x444) || !(BYTEORDER & 0xf)
1147 fatal("Unknown BYTEORDER\n");
1152 for (o = BYTEORDER - 0x1111, s = 0; s < (sizeof(long)*8); o >>= 4, s += 8) {
1153 u.c[o & 0xf] = (l >> s) & 255;
1166 char c[sizeof(long)];
1169 #if BYTEORDER == 0x1234
1170 u.c[0] = (l >> 24) & 255;
1171 u.c[1] = (l >> 16) & 255;
1172 u.c[2] = (l >> 8) & 255;
1176 #if ((BYTEORDER - 0x1111) & 0x444) || !(BYTEORDER & 0xf)
1177 fatal("Unknown BYTEORDER\n");
1184 for (o = BYTEORDER - 0x1111, s = 0; s < (sizeof(long)*8); o >>= 4, s += 8) {
1185 l |= (u.c[o & 0xf] & 255) << s;
1192 #endif /* BYTEORDER != 0x4321 */
1193 #endif /* HAS_HTONS */
1202 register int this, that;
1205 int doexec = strNE(cmd,"-");
1209 this = (*mode == 'w');
1214 taintproper("Insecure dependency in exec");
1217 while ((pid = (doexec?vfork():fork())) < 0) {
1218 if (errno != EAGAIN) {
1221 fatal("Can't fork");
1230 if (p[THIS] != (*mode == 'r')) {
1231 dup2(p[THIS], *mode == 'r');
1235 #if !defined(HAS_FCNTL) || !defined(F_SETFD)
1241 for (fd = maxsysfd + 1; fd < NOFILE; fd++)
1244 do_exec(cmd); /* may or may not use the shell */
1247 if (tmpstab = stabent("$",allstabs))
1248 str_numset(STAB_STR(tmpstab),(double)getpid());
1250 hclear(pidstatus, FALSE); /* we have no children */
1255 do_execfree(); /* free any memory malloced by child on vfork */
1257 if (p[that] < p[this]) {
1258 dup2(p[this], p[that]);
1262 str = afetch(fdpid,p[this],TRUE);
1263 str->str_u.str_useful = pid;
1265 return fdopen(p[this], mode);
1274 struct stat tmpstatbuf;
1276 fprintf(stderr,"%s", s);
1277 for (fd = 0; fd < 32; fd++) {
1278 if (fstat(fd,&tmpstatbuf) >= 0)
1279 fprintf(stderr," %d",fd);
1281 fprintf(stderr,"\n");
1290 #if defined(HAS_FCNTL) && defined(F_DUPFD)
1292 fcntl(oldfd, F_DUPFD, newfd);
1301 while ((fd = dup(oldfd)) != newfd) /* good enough for low fd's */
1304 close(fdtmp[--fdx]);
1315 void (*hstat)(), (*istat)(), (*qstat)();
1317 int (*hstat)(), (*istat)(), (*qstat)();
1323 str = afetch(fdpid,fileno(ptr),TRUE);
1324 astore(fdpid,fileno(ptr),Nullstr);
1326 pid = (int)str->str_u.str_useful;
1327 hstat = signal(SIGHUP, SIG_IGN);
1328 istat = signal(SIGINT, SIG_IGN);
1329 qstat = signal(SIGQUIT, SIG_IGN);
1330 pid = wait4pid(pid, &status, 0);
1331 signal(SIGHUP, hstat);
1332 signal(SIGINT, istat);
1333 signal(SIGQUIT, qstat);
1334 return(pid < 0 ? pid : status);
1338 wait4pid(pid,statusp,flags)
1350 return wait4((pid==-1)?0:pid,statusp,flags,Null(struct rusage *));
1353 return waitpid(pid,statusp,flags);
1356 sprintf(spid, "%d", pid);
1357 str = hfetch(pidstatus,spid,strlen(spid),FALSE);
1358 if (str != &str_undef) {
1359 *statusp = (int)str->str_u.str_useful;
1360 hdelete(pidstatus,spid,strlen(spid));
1367 hiterinit(pidstatus);
1368 if (entry = hiternext(pidstatus)) {
1369 pid = atoi(hiterkey(entry,statusp));
1370 str = hiterval(entry);
1371 *statusp = (int)str->str_u.str_useful;
1372 sprintf(spid, "%d", pid);
1373 hdelete(pidstatus,spid,strlen(spid));
1378 fatal("Can't do waitpid with flags");
1380 while ((result = wait(statusp)) != pid && pid > 0 && result >= 0)
1381 pidgone(result,*statusp);
1394 #if defined(HAS_WAIT4) || defined(HAS_WAITPID)
1399 sprintf(spid, "%d", pid);
1400 str = hfetch(pidstatus,spid,strlen(spid),TRUE);
1401 str->str_u.str_useful = status;
1409 register unsigned char *s1;
1410 register unsigned char *s2;
1416 if (tmp = *s1++ - *s2++)
1421 #endif /* HAS_MEMCMP */
1424 repeatcpy(to,from,len,count)
1426 register char *from;
1431 register char *frombase = from;
1439 while (count-- > 0) {
1440 for (todo = len; todo > 0; todo--) {
1447 #ifndef CASTNEGFLOAT
1455 # define BIGDOUBLE 2147483648.0
1457 return (unsigned long)(f-(long)(f/BIGDOUBLE)*BIGDOUBLE)|0x80000000;
1460 return (unsigned long)f;
1462 return (unsigned long)along;
1472 char *fa = rindex(a,'/');
1473 char *fb = rindex(b,'/');
1474 struct stat tmpstatbuf1;
1475 struct stat tmpstatbuf2;
1477 #define MAXPATHLEN 1024
1479 char tmpbuf[MAXPATHLEN+1];
1494 strncpy(tmpbuf, a, fa - a);
1495 if (stat(tmpbuf, &tmpstatbuf1) < 0)
1500 strncpy(tmpbuf, b, fb - b);
1501 if (stat(tmpbuf, &tmpstatbuf2) < 0)
1503 return tmpstatbuf1.st_dev == tmpstatbuf2.st_dev &&
1504 tmpstatbuf1.st_ino == tmpstatbuf2.st_ino;
1506 #endif /* !HAS_RENAME */
1509 scanoct(start, len, retlen)
1514 register char *s = start;
1515 register unsigned long retval = 0;
1517 while (len-- && *s >= '0' && *s <= '7') {
1519 retval |= *s++ - '0';
1521 *retlen = s - start;
1526 scanhex(start, len, retlen)
1531 register char *s = start;
1532 register unsigned long retval = 0;
1535 while (len-- && *s && (tmp = index(hexdigit, *s))) {
1537 retval |= (tmp - hexdigit) & 15;
1540 *retlen = s - start;