This is save_opts.c in view mode; [Download] [Up]
static char rcsid[] = "@(#)$Id: save_opts.c,v 5.1 1992/10/03 22:58:40 syd Exp $";
/*******************************************************************************
* The Elm Mail System - $Revision: 5.1 $ $State: Exp $
*
* Copyright (c) 1988-1992 USENET Community Trust
* Copyright (c) 1986,1987 Dave Taylor
*******************************************************************************
* Bug reports, patches, comments, suggestions should be sent to:
*
* Syd Weinstein, Elm Coordinator
* elm@DSI.COM dsinc!elm
*
*******************************************************************************
* $Log: save_opts.c,v $
* Revision 5.1 1992/10/03 22:58:40 syd
* Initial checkin as of 2.4 Release at PL0
*
*
******************************************************************************/
/** This file contains the routine needed to allow the users to change the
Elm parameters and then save the configuration in a ".elm/elmrc" file in
their home directory. With any luck this will allow them never to have
to actually EDIT the file!!
**/
#include "headers.h"
#include "s_elmrc.h"
#include <errno.h>
#undef onoff
#define onoff(n) (n == 1? "ON":"OFF")
#define absolute(x) ((x) < 0? -(x) : (x))
extern int errno;
extern char version_buff[];
char *error_description(), *sort_name(), *alias_sort_name(), *level_name();
long ftell();
#include "save_opts.h"
FILE *elminfo; /* informational file as needed... */
save_options()
{
/** Save the options currently specified to a file. This is a
fairly complex routine since it tries to put in meaningful
comments and such as it goes along. The comments are
extracted from the file ELMRC_INFO as defined in the sysdefs.h
file. THAT file has the format;
varname
<comment>
<comment>
<blank line>
and each comment is written ABOVE the variable to be added. This
program also tries to make 'pretty' stuff like the alternatives
and such.
**/
FILE *newelmrc;
char oldfname[SLEN], newfname[SLEN];
sprintf(newfname, "%s/%s", home, elmrcfile);
sprintf(oldfname, "%s/%s", home, old_elmrcfile);
/** first off, let's see if they already HAVE a .elm/elmrc file **/
save_file_stats(newfname);
if (access(newfname, ACCESS_EXISTS) != -1) {
/** YES! Copy it to the file ".old.elmrc".. **/
if (rename(newfname, oldfname) < 0)
dprint(2, (debugfile, "Unable to rename %s to %s\n",
newfname, oldfname));
(void) chown(oldfname, userid, groupid);
}
/** now let's open the datafile if we can... **/
if ((elminfo = fopen(ELMRC_INFO, "r")) == NULL)
error1(catgets(elm_msg_cat, ElmrcSet, ElmrcSavingWithoutComments,
"Warning: saving without comments! Can't get to %s."),
ELMRC_INFO);
/** next, open the new .elm/elmrc file... **/
if ((newelmrc = fopen(newfname, "w")) == NULL) {
error2(catgets(elm_msg_cat, ElmrcSet, ElmrcCantSaveConfig,
"Can't save configuration! Can't write to %s [%s]."),
newfname, error_description(errno));
return;
}
save_user_options(elminfo, newelmrc);
restore_file_stats(newfname);
error1(catgets(elm_msg_cat, ElmrcSet, ElmrcOptionsSavedIn,
"Options saved in file %s."), newfname);
}
static char *str_opt(x, f)
register int x;
int f;
{
static char buf[SLEN];
register char *s, *t;
s = strcpy(buf, "*ERROR*");
switch(save_info[x].flags & DT_MASK) {
case DT_STR:
if (save_info[x].flags & FL_NOSPC) {
for (t = SAVE_INFO_STR(x), s = buf; *t; ++t, ++s)
if ((*s = *t) == SPACE) *s='_';
*s = '\0';
s = buf;
} else
s = SAVE_INFO_STR(x);
break;
case DT_CHR:
sprintf(buf, "%c", *SAVE_INFO_CHR(x));
s = buf;
break;
case DT_BOL:
s = onoff(*SAVE_INFO_BOL(x));
break;
case DT_SRT:
if (f == FULL) {
s = sort_name(SHORT);
break;
}
sprintf(buf, "%d", *SAVE_INFO_NUM(x));
s = buf;
break;
case DT_ASR:
if (f == FULL) {
s = alias_sort_name(SHORT);
break;
}
sprintf(buf, "%d", *SAVE_INFO_NUM(x));
s = buf;
break;
case DT_NUM:
if (f == FULL) {
if (equal(save_info[x].name, "userlevel")) {
s = level_name(*SAVE_INFO_NUM(x));
break;
}
}
sprintf(buf, "%d", *SAVE_INFO_NUM(x));
s = buf;
break;
default:
break;
}
return(s);
}
find_opt(s)
char *s;
{
register int x, y;
for (x = 0; x < NUMBER_OF_SAVEABLE_OPTIONS; x++) {
y = strcmp(s, save_info[x].name);
if (y <= 0)
break;
}
if (y != 0)
return(-1);
return(x);
}
char *str_opt_nam(s, f)
char *s;
int f;
{
char *t = NULL;
int x;
x = find_opt(s);
if (x >= 0)
t = str_opt(x, f);
return(t);
}
save_user_options(elminfo_fd, newelmrc)
FILE *elminfo_fd, *newelmrc;
{
register int x, local_value;
register char *s;
/** save the information in the file. If elminfo_fd == NULL don't look
for comments!
**/
if (elminfo_fd != NULL)
build_offset_table(elminfo_fd);
fprintf(newelmrc, catgets(elm_msg_cat, ElmrcSet, ElmrcOptionsFile,
"#\n# .elm/elmrc - options file for the ELM mail system\n#\n"));
if (strlen(full_username) > 0)
MCfprintf(newelmrc, catgets(elm_msg_cat, ElmrcSet, ElmrcSavedAutoFor,
"# Saved automatically by ELM %s for %s\n#\n\n"),
version_buff, full_username);
else
fprintf(newelmrc, catgets(elm_msg_cat, ElmrcSet, ElmrcSavedAuto,
"# Saved automatically by ELM %s\n#\n\n"), version_buff);
fprintf(newelmrc, catgets(elm_msg_cat, ElmrcSet, ElmrcYesNoMeans,
"# For yes/no settings with ?, ON means yes, OFF means no\n"));
for (x = 0; x < NUMBER_OF_SAVEABLE_OPTIONS; x++) {
char buf[SLEN];
/** skip system-only options **/
if (save_info[x].flags & FL_SYS)
continue;
local_value = save_info[x].flags & FL_LOCAL;
s="";
switch(save_info[x].flags & DT_MASK) {
case DT_MLT:
case DT_SYN:
break;
case DT_ASR:
case DT_SRT:
s = str_opt(x, FULL);
break;
case DT_STR:
case DT_CHR:
case DT_BOL:
case DT_NUM:
s = str_opt(x, SHORT);
break;
case DT_WEE:
{ int len = 0 ,i;
add_comment(x, newelmrc);
if (!local_value)
fprintf(newelmrc, "### ");
fprintf(newelmrc, "%s = ", save_info[x].name);
len = strlen(save_info[x].name) + 4;
for (i = 0; i < weedcount && strcmp(weedlist[i], "*end-of-defaults*") !=0; i++)
/* intentional null loop body */;
while (i < weedcount && equal(weedlist[i], "*end-of-defaults*"))
i++;
while (i < weedcount) {
if (strlen(weedlist[i]) + len > 78) {
if (local_value)
fprintf(newelmrc, "\n\t");
else
fprintf(newelmrc, "\n###\t");
len = 8;
}
fprintf(newelmrc, "\"%s\" ", weedlist[i]);
len += strlen(weedlist[i]) + 4;
++i;
}
fprintf(newelmrc, "\t\"*end-of-user-headers*\"\n");
}
break;
case DT_ALT:
{ struct addr_rec *alts;
int len=0;
alts = *SAVE_INFO_ALT(x);
if (!alts) break;
add_comment(x, newelmrc);
if (!local_value)
fprintf(newelmrc, "### ");
fprintf(newelmrc, "%s = ", save_info[x].name);
len = strlen(save_info[x].name) + 4;
for ( ;alts; alts = alts->next) {
if (strlen(alts->address) + len > 78) {
if (local_value)
fprintf(newelmrc, "\n\t");
else
fprintf(newelmrc, "\n###\t");
len = 8;
}
fprintf(newelmrc, "%s ", alts->address);
len += strlen(alts->address) + 2;
}
}
fprintf(newelmrc,"\n");
break;
}
if (*s) {
add_comment(x, newelmrc);
if (local_value)
fprintf(newelmrc, "%s = %s\n", save_info[x].name, s);
else
fprintf(newelmrc, "### %s = %s\n", save_info[x].name, s);
}
}
fclose(newelmrc);
if ( elminfo_fd != NULL ) {
fclose(elminfo_fd);
}
}
add_comment(iindex, fd)
int iindex;
FILE *fd;
{
/** get to and add the comment to the file **/
char buffer[SLEN];
/** always put a blank line between options */
fputc('\n', fd);
/** add the comment from the comment file, if available **/
if (save_info[iindex].offset > 0L) {
if (fseek(elminfo, save_info[iindex].offset, 0) == -1) {
dprint(1,(debugfile,
"** error %s seeking to %ld in elm-info file!\n",
error_description(errno), save_info[iindex].offset));
}
else {
while (fgets(buffer, SLEN, elminfo) != NULL) {
if (buffer[0] != '#')
break;
fputs(buffer, fd);
}
}
}
}
build_offset_table(elminfo_fd)
FILE *elminfo_fd;
{
/** read in the info file and build the table of offsets.
This is a rather laborious puppy, but at least we can
do a binary search through the array for each element and
then we have it all at once!
**/
char line_buffer[SLEN];
while (fgets(line_buffer, SLEN, elminfo_fd) != NULL) {
if (strlen(line_buffer) > 1)
if (line_buffer[0] != '#' && !whitespace(line_buffer[0])) {
no_ret(line_buffer);
if (find_and_store_loc(line_buffer, ftell(elminfo_fd))) {
dprint(1, (debugfile,"** Couldn't find and store \"%s\" **\n",
line_buffer));
}
}
}
}
find_and_store_loc(name, offset)
char *name;
long offset;
{
/** given the name and offset, find it in the table and store it **/
int first = 0, last, middle, compare;
last = NUMBER_OF_SAVEABLE_OPTIONS;
while (first <= last) {
middle = (first+last) / 2;
if ((compare = strcmp(name, save_info[middle].name)) < 0) /* a < b */
last = middle - 1;
else if (compare == 0) { /* a = b */
save_info[middle].offset = offset;
return(0);
}
else /* greater */ /* a > b */
first = middle + 1;
}
return(-1);
}
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.