/*
* Copyright 1988 by Rayan S. Zachariassen, all rights reserved.
* This will be free software, but only when it is finished.
*/
/*LINTLIBRARY*/
/*
* The routines in this file will gulp in a configuration file in
* the syntax of printenv output, and allow access to the values read
* through an analogue of getenv().
*/
#include "mailer.h"
#include <ctype.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#include <string.h>
#include <errno.h>
#include "mail.h"
#include "libc.h"
static char *zenviron = NULL;
static int zenvlen = 0;
int
readzenv(file)
const char *file;
{
int fd;
struct stat stbuf;
fd = open(file, 0);
if (fd < 0) {
fprintf(stderr, "%s: open: %s: %s\n",
progname, file, strerror(errno));
return 0;
}
if (fstat(fd, &stbuf) < 0) {
fprintf(stderr, "%s: fstat: %s: %s\n",
progname, file, strerror(errno));
close(fd);
return 0;
}
zenviron = (char*)malloc((u_int) stbuf.st_size);
if (zenviron == NULL) {
fprintf(stderr, "%s: malloc(size of %s): %d: out of memory\n",
progname, file, (int)stbuf.st_size);
close(fd);
return 0;
}
zenvlen = (int)stbuf.st_size;
if (read(fd, zenviron, stbuf.st_size) != stbuf.st_size) {
fprintf(stderr, "%s: read: %s: %s\n",
progname, file, strerror(errno));
free(zenviron);
zenviron = NULL;
zenvlen = 0;
close(fd);
return 0;
}
close(fd);
return 1;
}
#define BOL 1
const char *
getzenv(variable)
const char *variable;
{
register int len, state;
register unsigned char *cp;
int varlen;
char *save;
if (variable == NULL)
return NULL;
varlen = strlen(variable);
if (varlen == 0)
return NULL;
len = zenvlen;
if (len <= 0) {
if (!readzenv(ZMAILER_ENV_FILE))
return NULL;
len = zenvlen;
if (len <= 0)
return NULL;
}
for (state = BOL, cp=(unsigned char*)zenviron; len > 0; --len, ++cp) {
if (*cp == '\n' || *cp == '\0') {
state = BOL;
continue;
}
if (state != BOL)
continue;
state = !BOL;
if (varlen < len && *variable == *cp
&& strncmp(variable, (void*)cp, varlen) == 0
&& *(cp+varlen) == '=')
break;
}
if (len > 0) {
for (cp += varlen+1; isascii(*cp) && isspace(*cp); ++cp)
if (*cp == '\n') {
*cp = '\0';
return (char*) cp; /* empty value */
}
/*
* We want to return cp, but also make sure the string is
* properly terminated.
*/
for (save = (char *)cp; *cp != '\0'; ++cp)
if (*cp == '\n') {
*cp = '\0';
break;
}
return save;
}
return NULL;
}
syntax highlighted by Code2HTML, v. 0.9.1