SCCSID(@
(#)util.c 4.2 8/31/83);
** STRIPQUOTES -- Strip quotes & quote bits from a string.
** Runs through a string and strips off unquoted quote
** characters and quote bits. This is done in place.
** s -- the string to strip.
** qf -- if set, remove actual `` " '' characters
** as well as the quote bits.
for (p
= q
= s
; (c
= *p
++) != '\0'; )
** QSTRLEN -- give me the string length assuming 0200 bits add a char
** s -- the string to measure.
** The length of s, including space for backslash escapes.
while ((c
= *s
++) != '\0')
** CAPITALIZE -- return a copy of a string, properly capitalized.
** s -- the string to capitalize.
** a pointer to a properly capitalized string.
while (!isalpha(*s
) && *s
!= '\0')
** XALLOC -- Allocate memory and bitch wildly on failure.
** THIS IS A CLUDGE. This should be made to give a proper
** error -- but after all, what can we do?
** sz -- size of area to allocate.
** pointer to data region.
syserr("Out of memory!!");
/* exit(EX_UNAVAILABLE); */
** COPYPLIST -- copy list of pointers.
** This routine is the equivalent of newstr for lists of
** list -- list of pointers to copy.
** Must be NULL terminated.
** copycont -- if TRUE, copy the contents of the vector
** (which must be a string) also.
copyplist(list
, copycont
)
for (vp
= list
; *vp
!= NULL
; vp
++)
newvp
= (char **) xalloc((vp
- list
) * sizeof *vp
);
bmove((char *) list
, (char *) newvp
, (vp
- list
) * sizeof *vp
);
for (vp
= newvp
; *vp
!= NULL
; vp
++)
** PRINTAV -- print argument vector.
** av -- argument vector.
printf("\n\t%08x=", *av
);
** LOWER -- turn letter into lower case.
** c -- character to turn into lower case.
if (isascii(c
) && isupper(c
))
** XPUTS -- put string doing control escapes.
while ((c
= *s
++) != '\0')
if (c
< 040 || c
>= 0177)
** MAKELOWER -- Translate a line into lower case
** p -- the string to translate. If NULL, return is
** String pointed to by p is translated to lower case.
for (; (c
= *p
) != '\0'; p
++)
if (isascii(c
) && isupper(c
))
** SAMEWORD -- return TRUE if the words are the same
** a, b -- the words to compare.
** TRUE if a & b match exactly (modulo case)
while (lower(*a
) == lower(*b
))
** CLEAR -- clear a block of memory
** p -- location to clear.
** l -- number of bytes to clear.
** BUILDFNAME -- build full name from gecos style entry.
** This routine interprets the strange entry that would appear
** in the GECOS field of the password file.
** login -- the login name of this user (for &).
** buf -- place to put the result.
buildfname(p
, login
, buf
)
while (*p
!= '\0' && *p
!= ',' && *p
!= ';' && *p
!= '%')
(void) strcpy(bp
, login
);
** SAFEFILE -- return true if a file exists and is safe for a user.
** fn -- filename to check.
** uid -- uid to compare against.
** mode -- mode bits that must match.
** TRUE if fn exists, is owned by uid, and matches mode.
if (stat(fn
, &stbuf
) >= 0 && stbuf
.st_uid
== uid
&&
(stbuf
.st_mode
& mode
) == mode
)
** FIXCRLF -- fix <CR><LF> in line.
** Looks for the <CR><LF> combination and turns it into the
** UNIX canonical <NL> character. It only takes one line,
** i.e., it is assumed that the first <NL> found is the end
** line -- the line to fix.
** stripnl -- if true, strip the newline also.
** line is changed in place.
** SYSLOG -- fake entry to fool lint
** DFOPEN -- determined file open
** This routine has the semantics of fopen, except that it will
** keep trying a few times to make this happen. The idea is that
** on very loaded systems, we may run out of resources (inodes,
** whatever), so this tries to get around it.
for (tries
= 0; tries
< 10; tries
++)
fp
= fopen(filename
, mode
);
if (errno
!= ENFILE
&& errno
!= EINTR
)
** PUTLINE -- put a line like fputs obeying SMTP conventions
** This routine always guarantees outputing a newline (or CRLF,
** as appropriate) at the end of the string.
** fp -- file to put it onto.
** m -- the mailer used to control output.
# define SMTPLINELIM 990 /* maximum line length */
/* strip out 0200 bits -- these can look like TELNET protocol */
if (bitnset(M_LIMITS
, m
->m_flags
))
while ((*p
++ &= ~0200) != 0)
/* find the end of the line */
/* check for line overflow */
while ((p
- l
) > SMTPLINELIM
&& bitnset(M_LIMITS
, m
->m_flags
))
register char *q
= &l
[SMTPLINELIM
- 1];
if (l
[0] == '.' && bitnset(M_XDOT
, m
->m_flags
))
if (l
[0] == '.' && bitnset(M_XDOT
, m
->m_flags
))
** XUNLINK -- unlink a file, doing logging as appropriate.
** f -- name of file to unlink.
syslog(LOG_DEBUG
, "%s: unlink %s\n", CurEnv
->e_id
, f
);
if (i
< 0 && LogLevel
> 21)
syslog(LOG_DEBUG
, "%s: unlink-fail %d", f
, errno
);
** SFGETS -- "safe" fgets -- times out and ignores random interrupts.
** buf -- place to put the input line.
** fp -- file to read from.
** NULL on error (including timeout).
static jmp_buf CtxReadTimeout
;
register EVENT
*ev
= NULL
;
if (setjmp(CtxReadTimeout
) != 0)
syserr("sfgets: timeout on read (mailer may be hung)");
ev
= setevent(ReadTimeout
, readtimeout
, 0);
} while (p
== NULL
&& errno
== EINTR
);
/* clear the event if it has not sprung */
/* clean up the books and exit */
longjmp(CtxReadTimeout
, 1);
** FGETFOLDED -- like fgets, but know about folded lines.
** buf -- place to put result.
** f -- file to read from.
** buf on success, NULL on error or EOF.
** buf gets lines from f, with continuation lines (lines
** with leading white space) appended. CRLF's are mapped
** into single newlines. Any trailing NL is stripped.
while (fgets(p
, n
, f
) != NULL
)
if (i
!= ' ' && i
!= '\t')
** CURTIME -- return current time.
** ATOBOOL -- convert a string representation to boolean.
** s -- string to convert. Takes "tTyY" as true,
** A boolean representation of the string.
if (*s
== '\0' || index("tTyY", *s
) != NULL
)
** ATOOCT -- convert a string representation to octal.
** s -- string to convert.
** An integer representing the string interpreted as an
while (*s
>= '0' && *s
<= '7')
i
= (i
<< 3) | (*s
++ - '0');
** WAITFOR -- wait for a particular process id.
** pid -- process id to wait for.
** -1 if pid never shows up.
} while ((i
>= 0 || errno
== EINTR
) && i
!= pid
);
** CLOSEALL -- close all extraneous file descriptors
** Closes all file descriptors except zero, one, and two.
** BITINTERSECT -- tell if two bitmaps intersect
** a, b -- the bitmaps in question
** TRUE if they have a non-null intersection
for (i
= BITMAPBYTES
/ sizeof (int); --i
>= 0; )
** BITZEROP -- tell if a bitmap is all zero
** map -- the bit map to check
** TRUE if map is all zero.
** FALSE if there are any bits set in map.
for (i
= BITMAPBYTES
/ sizeof (int); --i
>= 0; )