/* * 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 #include #include #include #ifdef HAVE_UNISTD_H #include #endif #include #include #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; }