static char rcsid[] = "@(#)$Id: rc_handle.c,v 1.40 2006/06/21 18:30:32 hurtta Exp $";
/******************************************************************************
* The Elm (ME+) Mail System - $Revision: 1.40 $ $State: Exp $
*
* Author: Kari Hurtta <hurtta+elm@posti.FMI.FI> (was hurtta+elm@ozone.FMI.FI)
****************************************************************************
*
* Some of code comes from ../src/read_rc.c and ../src/save_opts.c. These
* are following copyright:
*
* Copyright (c) 1988-1992 USENET Community Trust
* Copyright (c) 1986,1987 Dave Taylor
*****************************************************************************/
#include "headers.h"
#include "rc_imp.h"
#include "save_opts.h"
#ifdef USE_DLOPEN
#include "shared_imp.h"
#endif
#include "s_elm.h"
DEBUG_VAR(Debug,__FILE__,"config");
#ifdef ANSI_C
static rc_parse_line dt_SYN_parse_line;
#endif
static int dt_SYN_parse_line(r,lcl,value,lineno,filename, negate)
struct rc_save_info_rec *r;
int lcl;
char *value;
int lineno;
char *filename;
int negate;
{
if (negate) {
char buffer[SLEN];
buffer[0] = '!';
strfcpy(buffer+1, r->val.str, sizeof buffer -1);
if ( do_set(lcl,buffer,value,filename))
return 1;
} else {
if ( do_set(lcl, r->val.str, value, filename))
return 1;
}
return 0;
}
#ifdef ANSI_C
static rc_parse_cline BAD_parse_cline;
#endif
static int BAD_parse_cline(r,lcl,value,lineno,filename)
struct rc_save_info_rec *r;
int lcl;
char *value;
int lineno;
char *filename;
{
lib_error(CATGETS(elm_msg_cat, ElmSet, ElmBadContinuationInElmrc,
"Key \"%s\" does not accept continuation lines in line %d in \"%s\" file"),
r->name,lineno,filename);
return 0;
}
#if ANSI_C
static rc_print_value NO_print_value;
#endif
static void NO_print_value(F,r,comment)
FILE *F;
struct rc_save_info_rec *r;
int comment;
{
/* Empty */
}
#if ANSI_C
static rc_get_value NO_get_value;
#endif
static char * NO_get_value(r)
struct rc_save_info_rec *r;
{
return "*bad*";
}
struct rc_type rc_DT_SYN = { RCTYPE_magic,
dt_SYN_parse_line, BAD_parse_cline,
NO_print_value, NO_get_value };
#ifdef ANSI_C
static rc_parse_line dt_STR_parse_line;
#endif
static int dt_STR_parse_line(r,lcl,value,lineno,filename, negate)
struct rc_save_info_rec *r;
int lcl;
char *value;
int lineno;
char *filename;
int negate;
{
if (negate) {
lib_error(CATGETS(elm_msg_cat, ElmSet, ElmBadNegate,
"!%s is not supported in line %d in \"%s\" file"),
r->name,lineno,filename);
return 0;
}
if (strlen(value) >= r->size_val) {
lib_error(CATGETS(elm_msg_cat, ElmSet, ElmLongValueInElmrc,
"Value of \"%s\" in line %d in \"%s\" file is too long"),
r->name,lineno,filename);
return 0;
}
strfcpy(r->val.str, value, r->size_val);
if (r->flags & FL_NOSPC) {
char *s;
for (s = r->val.str; *s; ++s)
if (*s == '_') *s=' ';
}
return 1;
}
/* Returns pointer to static area */
#if ANSI_C
static rc_get_value dt_STR_get_value;
#endif
static char * dt_STR_get_value(r)
struct rc_save_info_rec *r;
{
if (r->flags & FL_NOSPC) {
static char buffer[SLEN];
char *t, *s;
for (t = r->val.str, s = buffer;
*t && s - buffer < sizeof buffer -1;
++t, ++s)
if ((*s = *t) == ' ')
*s='_';
*s = '\0';
return buffer;
} else
return r->val.str;
}
#if ANSI_C
static rc_print_value dt_STR_print_value;
#endif
static void dt_STR_print_value(F,r,comment)
FILE *F;
struct rc_save_info_rec *r;
int comment;
{
char * s = dt_STR_get_value(r);
if (comment)
fprintf(F, "### ");
fprintf(F, "%s = %s\n", r->name, s);
DPRINT(Debug,9,(&Debug,
" option \"%s\", value=\"%s\"\n",
r->name,s ));
}
struct rc_type rc_DT_STR = { RCTYPE_magic,
dt_STR_parse_line, BAD_parse_cline,
dt_STR_print_value, dt_STR_get_value };
#ifdef ANSI_C
static rc_parse_line dt_NUM_parse_line;
#endif
static int dt_NUM_parse_line(r,lcl,value,lineno,filename, negate)
struct rc_save_info_rec *r;
int lcl;
char *value;
int lineno;
char *filename;
int negate;
{
char *p;
long l = strtol(value,&p,10);
if (negate) {
lib_error(CATGETS(elm_msg_cat, ElmSet, ElmBadNegate,
"!%s is not supported in line %d in \"%s\" file"),
r->name,lineno,filename);
return 0;
}
*(r->val.num) = l;
return 1;
}
#if ANSI_C
static rc_print_value dt_NUM_print_value;
#endif
static void dt_NUM_print_value(F,r,comment)
FILE *F;
struct rc_save_info_rec *r;
int comment;
{
if (comment)
fprintf(F, "### ");
fprintf(F, "%s = %d\n", r->name,
*r->val.num);
DPRINT(Debug,9,(&Debug,
" option \"%s\", value=%d\n",
r->name,*r->val.num ));
}
/* Returns static pointer */
#if ANSI_C
static rc_get_value dt_NUM_get_value;
#endif
static char * dt_NUM_get_value(r)
struct rc_save_info_rec *r;
{
static char * buffer = NULL;
if (buffer)
free(buffer);
buffer = elm_message(FRM("%d"), *r->val.num);
return buffer;
}
struct rc_type rc_DT_NUM = { RCTYPE_magic,
dt_NUM_parse_line, BAD_parse_cline,
dt_NUM_print_value, dt_NUM_get_value };
#ifdef ANSI_C
static rc_parse_line dt_BOL_parse_line;
#endif
static int dt_BOL_parse_line(r,lcl,value,lineno,filename, negate)
struct rc_save_info_rec *r;
int lcl;
char *value;
int lineno;
char *filename;
int negate;
{
if (negate) {
if (r->flags & FL_OR)
*(r->val.bol) |= !is_it_on(value);
else if (r->flags & FL_AND)
*(r->val.bol) &= !is_it_on(value);
else
*(r->val.bol) = !is_it_on(value);
} else {
if (r->flags & FL_OR)
*(r->val.bol) |= is_it_on(value);
else if (r->flags & FL_AND)
*(r->val.bol) &= is_it_on(value);
else
*(r->val.bol) = is_it_on(value);
}
return 1;
}
#if ANSI_C
static rc_print_value dt_BOL_print_value;
#endif
static void dt_BOL_print_value(F,r,comment)
FILE *F;
struct rc_save_info_rec *r;
int comment;
{
char * s;
if (comment)
fprintf(F, "### ");
s = *r->val.bol ? "ON" : "OFF";
fprintf(F, "%s = %s\n", r->name, s);
DPRINT(Debug,9,(&Debug,
" option \"%s\", value=%s\n",
r->name,s ));
}
#if ANSI_C
static rc_get_value dt_BOL_get_value;
#endif
static char * dt_BOL_get_value(r)
struct rc_save_info_rec *r;
{
return *r->val.bol ? "ON" : "OFF";
}
struct rc_type rc_DT_BOL = { RCTYPE_magic,
dt_BOL_parse_line, BAD_parse_cline,
dt_BOL_print_value, dt_BOL_get_value };
#ifdef ANSI_C
static rc_parse_line dt_CHR_parse_line;
#endif
static int dt_CHR_parse_line(r,lcl,value,lineno,filename, negate)
struct rc_save_info_rec *r;
int lcl;
char *value;
int lineno;
char *filename;
int negate;
{
if (negate) {
lib_error(CATGETS(elm_msg_cat, ElmSet, ElmBadNegate,
"!%s is not supported in line %d in \"%s\" file"),
r->name,lineno,filename);
return 0;
}
*(r->val.chr) = value[0];
return 1;
}
#if ANSI_C
static rc_print_value dt_CHR_print_value;
#endif
static void dt_CHR_print_value(F,r,comment)
FILE *F;
struct rc_save_info_rec *r;
int comment;
{
if (comment)
fprintf(F, "### ");
fprintf(F, "%s = %c\n", r->name, *r->val.chr);
DPRINT(Debug,9,(&Debug,
" option \"%s\", value=%c\n",
r->name, *r->val.chr));
}
#if ANSI_C
static rc_get_value dt_CHR_get_value;
#endif
static char * dt_CHR_get_value(r)
struct rc_save_info_rec *r;
{
static char buffer[2];
buffer[0] = *r->val.chr;
buffer[1] = '\0';
return buffer;
}
struct rc_type rc_DT_CHR = { RCTYPE_magic,
dt_CHR_parse_line, BAD_parse_cline,
dt_CHR_print_value, dt_CHR_get_value };
#ifdef ANSI_C
static rc_parse_line dt_SORT_parse_line;
#endif
static int dt_SORT_parse_line(r,lcl,value,lineno,filename, negate)
struct rc_save_info_rec *r;
int lcl;
char *value;
int lineno;
char *filename;
int negate;
{
char buffer[SLEN];
char *s = buffer;
int f,y;
f = 1;
strfcpy(buffer, shift_lower(value), sizeof buffer);
if (strncmp(s, "rev-", 4) == 0 ||
strncmp(s, "reverse-", 8) == 0) {
f = -f;
s = index(s, '-') + 1;
}
if (negate)
f = -f;
for (y= 0; r->val.sort->sortval[y].kw; y++) {
if (equal(s, r->val.sort->sortval[y].kw))
break;
}
if (r->val.sort->sortval[y].kw) {
r->val.sort->val = f > 0 ?
r->val.sort->sortval[y].sv :
- r->val.sort->sortval[y].sv;
} else {
lib_error(CATGETS(elm_msg_cat, ElmSet,
ElmBadSortKeyInElmrc,
"I can't understand sort key \"%s\" in line %d in \"%s\" file"),
value, lineno, filename);
return 0;
}
return 1;
}
static char * give_sort_value P_((struct dt_sort_info *ptr));
static char * give_sort_value(ptr)
struct dt_sort_info *ptr;
{
int y;
for (y= 0; ptr->sortval[y].kw; y++) {
if (ptr->sortval[y].sv == ptr->val)
return ptr->sortval[y].kw;
else if (ptr->sortval[y].sv == - ptr->val) {
static char * buffer = NULL;
buffer = strmcpy(buffer,"reverse-");
buffer = strmcat(buffer, ptr->sortval[y].kw);
return buffer;
}
}
return "*bad*";
}
#if ANSI_C
static rc_get_value dt_SORT_get_value;
#endif
static char * dt_SORT_get_value(r)
struct rc_save_info_rec *r;
{
return give_sort_value(r->val.sort);
}
CONST char * give_dt_sort_as_str(ptr)
struct dt_sort_info *ptr;
{
return give_sort_value(ptr);
}
int give_dt_sort_as_int(ptr)
struct dt_sort_info *ptr;
{
return ptr->val;
}
void set_dt_sort_as_int(ptr,val)
struct dt_sort_info *ptr;
int val;
{
ptr->val = val;
}
#if ANSI_C
static rc_print_value dt_SORT_print_value;
#endif
static void dt_SORT_print_value(F,r,comment)
FILE *F;
struct rc_save_info_rec *r;
int comment;
{
if (comment)
fprintf(F, "### ");
fprintf(F, "%s = %s\n", r->name,
dt_SORT_get_value(r));
}
struct rc_type rc_DT_SORT = { RCTYPE_magic,
dt_SORT_parse_line, BAD_parse_cline,
dt_SORT_print_value, dt_SORT_get_value };
#ifdef ANSI_C
static rc_parse_line dt_MLT_parse_line;
#endif
static int dt_MLT_parse_line(r,lcl,value,lineno,filename, negate)
struct rc_save_info_rec *r;
int lcl;
char *value;
int lineno;
char *filename;
int negate;
{
int ok = 1;
char **s;
if (negate) {
lib_error(CATGETS(elm_msg_cat, ElmSet, ElmBadNegate,
"!%s is not supported in line %d in \"%s\" file"),
r->name,lineno,filename);
return 0;
}
for (s = r->val.mlt; *s; ++s) {
if (!do_set(lcl, *s, value, filename))
ok = 0;
}
return ok;
}
struct rc_type rc_DT_MLT = { RCTYPE_magic,
dt_MLT_parse_line, BAD_parse_cline,
NO_print_value, NO_get_value };
#ifdef ANSI_C
static rc_parse_line dt_PRM_parse_line;
#endif
static int dt_PRM_parse_line(r,lcl,value,lineno,filename, negate)
struct rc_save_info_rec *r;
int lcl;
char *value;
int lineno;
char *filename;
int negate;
{
char *s = value;
int m = 0;
char *modecharp = "rwxrwxrwx";
int modebit = 0400;
char c;
if (negate) {
lib_error(CATGETS(elm_msg_cat, ElmSet, ElmBadNegate,
"!%s is not supported in line %d in \"%s\" file"),
r->name,lineno,filename);
return 0;
}
while ((c = *s++) != '\0') {
if (c == *modecharp)
m |= modebit;
else if (c != '-') {
lib_error(CATGETS(elm_msg_cat, ElmSet,
ElmBadModeInElmrc,
"I can't understand file permissions \"%s\" in line %d in \"%s\" file"),
value, lineno,filename);
return 0;
}
modecharp++;
modebit >>= 1;
}
if (*modecharp != '\0') {
lib_error(CATGETS(elm_msg_cat, ElmSet, ElmBadModeInElmrc,
"I can't understand file permissions \"%s\" in line %d in \"%s\" file"),
value, lineno,filename);
return 0;
}
*(r->val.num) = m;
return 1;
}
#if ANSI_C
static rc_print_value dt_PRM_print_value;
#endif
static void dt_PRM_print_value(F,r,comment)
FILE *F;
struct rc_save_info_rec *r;
int comment;
{
char *s = mode_to_str(*(r->val.num));
if (comment)
fprintf(F, "### ");
fprintf(F, "%s = %s\n", r->name, s);
}
#if ANSI_C
static rc_get_value dt_PRM_get_value;
#endif
static char * dt_PRM_get_value(r)
struct rc_save_info_rec *r;
{
return mode_to_str(*(r->val.num));
}
struct rc_type rc_DT_PRM = { RCTYPE_magic,
dt_PRM_parse_line, BAD_parse_cline,
dt_PRM_print_value, dt_PRM_get_value };
#ifdef ANSI_C
static rc_parse_line dt_FUNC_parse_line;
#endif
static int dt_FUNC_parse_line(r,lcl,value,lineno,filename, negate)
struct rc_save_info_rec *r;
int lcl;
char *value;
int lineno;
char *filename;
int negate;
{
if (negate) {
lib_error(CATGETS(elm_msg_cat, ElmSet, ElmBadNegate,
"!%s is not supported in line %d in \"%s\" file"),
r->name,lineno,filename);
return 0;
}
if (!r->func_val(&value,1,lineno,filename)) {
lib_error(CATGETS(elm_msg_cat, ElmSet, ElmBadValueInElmrc,
"Value of \"%s\" in line %d in \"%s\" file is bad"),
r->name,lineno,filename);
return 0;
}
return 1;
}
#if ANSI_C
static rc_print_value dt_FUNC_print_value;
#endif
static void dt_FUNC_print_value(F,r,comment)
FILE *F;
struct rc_save_info_rec *r;
int comment;
{
char *s = NULL;
r->func_val(&s,0,0,NULL);
if (s) {
if (comment)
fprintf(F, "### ");
fprintf(F, "%s = %s\n", r->name, s);
}
}
#if ANSI_C
static rc_get_value dt_FUNC_get_value;
#endif
static char * dt_FUNC_get_value(r)
struct rc_save_info_rec *r;
{
char *s = NULL;
r->func_val(&s,0,0,NULL);
return s;
}
struct rc_type rc_DT_FUNC = { RCTYPE_magic,
dt_FUNC_parse_line, BAD_parse_cline,
dt_FUNC_print_value, dt_FUNC_get_value };
#ifdef ANSI_C
static rc_parse_line dt_LONG_parse_line;
#endif
static int dt_LONG_parse_line(r,lcl,value,lineno,filename, negate)
struct rc_save_info_rec *r;
int lcl;
char *value;
int lineno;
char *filename;
int negate;
{
char *p;
long l;
if (negate) {
lib_error(CATGETS(elm_msg_cat, ElmSet, ElmBadNegate,
"!%s is not supported in line %d in \"%s\" file"),
r->name,lineno,filename);
return 0;
}
l = strtol(value,&p,10);
*(r->val.l_num) = l;
return 1;
}
#if ANSI_C
static rc_print_value dt_LONG_print_value;
#endif
static void dt_LONG_print_value(F,r,comment)
FILE *F;
struct rc_save_info_rec *r;
int comment;
{
if (comment)
fprintf(F, "### ");
fprintf(F, "%s = %ld\n", r->name, *r->val.l_num);
}
#if ANSI_C
static rc_get_value dt_LONG_get_value;
#endif
static char * dt_LONG_get_value(r)
struct rc_save_info_rec *r;
{
static char * buffer = NULL;
if (buffer)
free(buffer);
buffer = elm_message(FRM("%ld"), *r->val.l_num);
return buffer;
}
struct rc_type rc_DT_LONG = { RCTYPE_magic,
dt_LONG_parse_line, BAD_parse_cline,
dt_LONG_print_value, dt_LONG_get_value };
/* Appends expanded value to list
0 == failure
1 == succeed
*/
int expand_dt_path(ptr,fieldname,val, recursive)
struct dt_path_info *ptr;
char *fieldname;
char *val;
int recursive; /* 0 if not recursive call */
{
int ret = 1;
int is_file = ptr->flags & PATH_file;
int is_dir = ptr->flags & PATH_dir;
int is_quote = (ptr->flags & PATH_quote) && 0 == recursive;
int is_expand = (ptr->flags & PATH_expand) && 0 == recursive;
int is_sep_comma = ptr->flags & PATH_sep_comma;
int is_sep_colon = ptr->flags & PATH_sep_colon;
int is_sep_space = 0 == recursive;
int is_quote_single = (ptr->flags & PATH_quote_single) && 0 == recursive;
int convert_underline = (ptr->flags & PATH_convert_underline)
&& 0 == recursive;
char *p;
char * start_val = NULL;
int q = 0;
int quit_flag = 0;
if (!recursive) {
DPRINT(Debug,8,(&Debug, "expand_dt_path: %s: %s\n",
fieldname,val));
if (0 == strcmp(val,"none") && 0 == ptr->nlen) {
/* Set dummy value indicating none ... */
ptr->list = safe_realloc(ptr->list,sizeof (ptr->list[0]));
ptr->list[0] = NULL;
ptr->nlen = 0;
return ret;
}
} else {
DPRINT(Debug,11,(&Debug, "expand_dt_path: %s: %s (recursive=%d)\n",
fieldname,val,recursive));
}
for (p = val; !quit_flag && (*p || start_val); p++) {
char * value = NULL;
/* Quarantee that we do not advance bast of \0 */
quit_flag = !*p;
/* Recognize \ escape only in quoted strings */
if (q && '\\' == *p) {
p++;
if (!*p) {
lib_error(CATGETS(elm_msg_cat, ElmSet,
ElmTrailingBackslashInElmrc,
"Trailing backslash (\\) on key \"%s\" value \"%s\""),
fieldname,val);
ret = 0;
}
continue;
}
if (!start_val) {
if (q || !*p) {
panic("RC PANIC",__FILE__,__LINE__,"expand_dt_path",
"Bad state on !start_val",0);
}
if (is_quote && '"' == *p) {
start_val = p+1;
q = '"';
continue;
}
if (is_quote_single && '\'' == *p) {
start_val = p+1;
q = '\'';
continue;
}
/* Empty values not allowed */
if (is_sep_comma && ',' == *p ||
is_sep_colon && ':' == *p ||
is_sep_space && ' ' == *p ||
is_sep_space && '\t' == *p)
continue;
start_val = p;
} else if (q) {
if (q == *p || '\0' == *p) {
int Len = p - start_val;
char * t, *s;
if (!*p) {
lib_error(CATGETS(elm_msg_cat, ElmSet,
ElmUnbalancedQuoteInElmrc,
"Unbalanced quote (%c) on key \"%s\" value \"%s\""),
q,fieldname,val);
ret = 0;
}
DPRINT(Debug,11,(&Debug,
"expand_dt_path (clip len=%d)=%.*s\n",
Len,Len,start_val));
value = safe_malloc( Len +1 );
for (s = start_val, t = value;
t-value < Len && s < p;) {
if ('\\' == *s)
s++;
*t++ = *s++;
}
*t = '\0';
q = 0;
DPRINT(Debug,11,(&Debug,
"expand_dt_path (unquoted)=%s\n",
value));
start_val = NULL;
goto expand_value;
}
} else {
if (is_sep_comma && ',' == *p ||
is_sep_colon && ':' == *p ||
is_sep_space && ' ' == *p ||
is_sep_space && '\t' == *p ||
'\0' == *p ) {
int Len = p - start_val;
DPRINT(Debug,11,(&Debug,
"expand_dt_path (clip len=%d)=%.*s\n",
Len,Len,start_val));
value = safe_malloc( Len +1 );
memcpy(value,start_val,Len);
value[Len] = '\0';
if (convert_underline) {
int i;
for (i = 0; i < Len; i++)
if ('_' == value[i])
value[i] = ' ';
}
start_val = NULL;
goto expand_value;
}
if (is_quote && '"' == *p) {
int Len = p - start_val;
/* Split on quote */
q = '"';
DPRINT(Debug,11,(&Debug,
"expand_dt_path (clip len=%d)=%.*s\n",
Len,Len,start_val));
value = safe_malloc( Len +1 );
memcpy(value,start_val,Len);
value[Len] = '\0';
start_val = NULL;
goto expand_value;
}
if (is_quote_single && '\'' == *p) {
int Len = p - start_val;
/* Split on quote */
q = '\'';
DPRINT(Debug,11,(&Debug,
"expand_dt_path (clip len=%d)=%.*s\n",
Len,Len,start_val));
value = safe_malloc( Len +1 );
memcpy(value,start_val,Len);
value[Len] = '\0';
start_val = NULL;
goto expand_value;
}
}
if (0) {
expand_value:
if (is_expand) {
char buffer[1024];
int v = expand_path(buffer,value,sizeof buffer);
if (v < 0) {
lib_error(CATGETS(elm_msg_cat, ElmSet,
ElmBadVariableInElmrc,
"Bad variable on key \"%s\" value \"%s\""),
fieldname,val);
ret = 0;
} else if (v > 0) {
DPRINT(Debug,11,(&Debug,
"expand_dt_path (expanded)=%s\n",
buffer));
if (recursive < 2 &&
(is_sep_colon || is_sep_comma)) {
if (!expand_dt_path(ptr,fieldname,buffer,recursive+1))
ret = 0;
free(value); value = NULL;
continue;
}
value = strmcpy(value,buffer);
}
}
if (is_file || is_dir) {
struct stat S;
if ('/' != value[0]) {
if (0 == recursive) {
DPRINT(Debug,9,(&Debug,
"expand_dt_path not absolute=%s\n",
value));
lib_error(CATGETS(elm_msg_cat, ElmSet,
ElmNotAbsoluteInElmrc,
"Path component \"%s\" not absolute on key \"%s\" value \"%s\""),
value,fieldname,val);
ret = 0;
}
free(value); value = NULL;
continue;
}
if (-1 == stat(value,&S)) {
DPRINT(Debug,9,(&Debug,
"expand_dt_path not accessib=%s\n",
value));
if (0 == recursive) {
lib_error(CATGETS(elm_msg_cat, ElmSet,
ElmNotAccessibleInElmrc,
"Path component \"%s\" not accessible on key \"%s\" value \"%s\""),
value,fieldname,val);
ret = 0;
}
free(value); value = NULL;
continue;
}
if (is_dir &&
#ifdef S_ISDIR
!S_ISDIR(S.st_mode)
#else
S_IFDIR != (S.st_mode & S_IFMT)
#endif
) {
DPRINT(Debug,9,(&Debug,
"expand_dt_path not director=%s\n",
value));
if (0 == recursive) {
lib_error(CATGETS(elm_msg_cat, ElmSet,
ElmNotDirInElmrc,
"Path component \"%s\" not a directory on key \"%s\" value \"%s\""),
value,fieldname,val);
ret = 0;
}
free(value); value = NULL;
continue;
}
if (is_file &&
#ifdef S_ISREG
!S_ISREG(S.st_mode)
#else
S_IFREG != (S.st_mode & S_IFMT)
#endif
) {
DPRINT(Debug,9,(&Debug,
"expand_dt_path not a file =%s\n",
value));
if (0 == recursive) {
lib_error(CATGETS(elm_msg_cat, ElmSet,
ElmNotFileInElmrc,
"Path component \"%s\" not a file on key \"%s\" value \"%s\""),
value,fieldname,val);
ret = 0;
}
free(value); value = NULL;
continue;
}
}
DPRINT(Debug,9,(&Debug,
"expand_dt_path [%d]=%s\n",
ptr->nlen,value));
ptr->list = safe_realloc(ptr->list,
(ptr->nlen+1)* sizeof (ptr->list[0]));
ptr->list[ptr->nlen++] = value;
if (q) {
DPRINT(Debug,9,(&Debug,
"expand_dt_path : Starting next quoted value...\n"));
start_val = p+1;
}
}
}
if (start_val || q) {
panic("RC PANIC",__FILE__,__LINE__,"expand_dt_path",
"Bad state on end",0);
}
if (!recursive) {
DPRINT(Debug,9,(&Debug,
"expand_dt_path=%d\n",
ret));
} else {
DPRINT(Debug,11,(&Debug,
"expand_dt_path=%d (recursive=%d)\n",
ret,recursive));
}
if (ptr->nlen > 0) {
/* Add trailing NULL */
ptr->list = safe_realloc(ptr->list,
(ptr->nlen+1)* sizeof (ptr->list[0]));
ptr->list[ptr->nlen] = NULL;
}
return ret;
}
char ** give_dt_path_as_elems(ptr, fieldname)
struct dt_path_info *ptr;
char * fieldname;
{
if (!ptr->list && ptr->unexpanded)
expand_dt_path(ptr,fieldname,ptr->unexpanded,0);
return ptr->list;
}
char * give_dt_path_as_str(ptr,fieldname)
struct dt_path_info *ptr;
char * fieldname;
{
char *res,*p;
int sep;
int quote;
int i,L = 1;
if (!ptr->list && ptr->unexpanded)
expand_dt_path(ptr,fieldname,ptr->unexpanded,0);
if (!ptr->list)
return NULL;
if (ptr->list && 0 == ptr->nlen) {
res = safe_strdup("none");
DPRINT(Debug,9,(&Debug,
"give_dt_path_as_str=%s\n",res));
return res;
}
for (i = 0; i < ptr->nlen; i++)
L += strlen(ptr->list[i]) +1;
if (ptr->flags & PATH_sep_comma) sep = ',';
else if (ptr->flags & PATH_sep_colon) sep = ':';
else sep = ' ';
if (ptr->flags & PATH_quote) quote = '"';
else if (ptr->flags & PATH_quote_single) quote = '\'';
else quote = 0;
if (quote)
L += ptr->nlen * 2;
res = safe_malloc(L);
for (i = 0, p = res; i < ptr->nlen;i++) {
int l = strlen(ptr->list[i]);
if (p+l+1 + (quote ? 2 : 0) >= res+L)
panic("RC PANIC",__FILE__,__LINE__,"give_dt_path_as_str",
"Overflow",0);
if (i > 0)
*p++ = sep;
if (quote)
*p++ = quote;
memcpy(p,ptr->list[i],l);
p += l;
if (quote)
*p++ = quote;
}
*p = '\0';
DPRINT(Debug,9,(&Debug,
"give_dt_path_as_str (len=%d)=%s\n",L,res));
return res;
}
#if ANSI_C
static rc_parse_line dt_PATH_parse_line;
#endif
static int dt_PATH_parse_line(r,lcl,value,lineno,filename,negate)
struct rc_save_info_rec *r;
int lcl;
char *value;
int lineno;
char *filename;
int negate;
{
if (negate) {
lib_error(CATGETS(elm_msg_cat, ElmSet, ElmBadNegate,
"!%s is not supported in line %d in \"%s\" file"),
r->name,lineno,filename);
return 0;
}
r->val.path->unexpanded = strmcpy(r->val.path->unexpanded,value);
/* Free old value */
if (r->val.path->list) {
int i;
for (i = 0; i < r->val.path->nlen; i++) {
if (r->val.path->list[i]) {
r->val.path->list[i] = NULL;
}
}
free(r->val.path->list);
}
r->val.path->list = NULL;
r->val.path->nlen = 0;
return 1;
}
#if ANSI_C
static rc_parse_cline dt_PATH_parse_cline;
#endif
static int dt_PATH_parse_cline(r,lcl,value,lineno,filename)
struct rc_save_info_rec *r;
int lcl;
char *value;
int lineno;
char *filename;
{
int ret = 1;
/* First line is unexpanded so expand it .... */
if (r->val.path->unexpanded) {
ret = expand_dt_path(r->val.path,
r->name,r->val.path->unexpanded,0);
if (!ret) {
lib_error(CATGETS(elm_msg_cat, ElmSet, ElmBadValueInElmrc,
"Value of \"%s\" in line %d in \"%s\" file is bad"),
r->name,lineno-1,filename);
}
free(r->val.path->unexpanded); r->val.path->unexpanded = NULL;
}
if (!expand_dt_path(r->val.path,r->name,value,0)) {
lib_error(CATGETS(elm_msg_cat, ElmSet, ElmBadValueInElmrc,
"Value of \"%s\" in line %d in \"%s\" file is bad"),
r->name,lineno,filename);
ret = 0;
}
return ret;
}
#if ANSI_C
static rc_print_value dt_PATH_print_value;
#endif
static void dt_PATH_print_value(F,r,comment)
FILE *F;
struct rc_save_info_rec *r;
int comment;
{
if (r->val.path->unexpanded) {
if (comment)
fprintf(F, "### ");
fprintf(F, "%s = %s\n", r->name, r->val.path->unexpanded);
} else {
int i;
int len = strlen(r->name) + 3;
if (comment)
fprintf(F, "### ");
fprintf(F, "%s = ",r->name);
if (r->val.path->list && 0 == r->val.path->nlen) {
fprintf(F, "none");
}
for (i = 0; i < r->val.path->nlen; i++) {
/* NOTE: space is always valid separator even when
PATH_sep_comma or PATH_sep_colon is set */
if (i > 0) {
if (len + strlen(r->val.path->list[i]) > 70) {
fprintf(F, "\n");
if (comment)
fprintf(F, "### ");
fprintf(F, "\t");
len = 8;
} else
fprintf(F, " ");
}
if (r->val.path->flags & PATH_quote)
elm_fprintf(F,FRM("%Q"),r->val.path->list[i]);
else if (r->val.path->flags & PATH_quote_single) {
fputc('\'',F);
fputs(r->val.path->list[i],F);
fputc('\'',F);
} else
fputs(r->val.path->list[i],F);
len += strlen(r->val.path->list[i]) + 1;
}
fprintf(F, "\n");
}
}
struct rc_type rc_DT_PATH = { RCTYPE_magic,
dt_PATH_parse_line, dt_PATH_parse_cline,
dt_PATH_print_value, NO_get_value };
#ifdef ANSI_C
static rc_parse_line dt_OBS_parse_line;
#endif
static int dt_OBS_parse_line(r,lcl,value,lineno,filename, negate)
struct rc_save_info_rec *r;
int lcl;
char *value;
int lineno;
char *filename;
int negate;
{
/* This message is not perhaps very visible, because
ELm starts anyway, but it was requested on that way.
*/
lib_error(CATGETS(elm_msg_cat, ElmSet, ElmObsoleteInElmrc,
"Elmrc variable \"%s\" is obsolete and should be removed from line %d in \"%s\" file"),
r->name,lineno,filename);
return 1; /* Mark as succeed */
}
struct rc_type rc_DT_OBS = { RCTYPE_magic,
dt_OBS_parse_line, BAD_parse_cline,
NO_print_value, NO_get_value };
static void metamail_expand(struct dt_estr_info *ptr);
static void metamail_expand(ptr)
struct dt_estr_info *ptr;
{
if (getenv("NOMETAMAIL")) {
if (ptr->expanded)
free(ptr->expanded);
ptr->expanded = NULL;
} else {
ptr->expanded = strmcpy(ptr->expanded,"metamail");
}
}
/*
0 == failure
1 == succeed
*/
static void estr_set_expanded P_((struct dt_estr_info *ptr,
const char *buffer));
static void estr_set_expanded(ptr,buffer)
struct dt_estr_info *ptr;
CONST char *buffer;
{
/* Fix shell if needed */
if (ptr->flags & ESTR_bin) {
if (buffer[0] != '/') {
char * A = elm_message(FRM("/bin/%s"), buffer);
if (ptr->expanded)
free(ptr->expanded);
ptr->expanded = A;
return;
}
}
ptr->expanded = strmcpy(ptr->expanded,buffer);
/* Fix temp_dir if needed */
if (ptr->flags & ESTR_slash) {
int l = strlen(buffer);
if (0 == l || buffer[l-1] != '/')
ptr->expanded = strmcat(ptr->expanded,"/");
}
}
int expand_dt_estr(ptr,fieldname,val)
struct dt_estr_info *ptr;
char *fieldname;
char *val;
{
char buffer[1024];
int x;
if (ptr->flags & ESTR_none) {
if (0 == strcmp("none",ptr->unexpanded)) {
if (ptr->expanded)
free(ptr->expanded);
ptr->expanded = NULL;
return 1;
}
}
if (ptr->flags & ESTR_metamail) {
if (0 == strcmp("metamail",ptr->unexpanded)) {
metamail_expand(ptr);
return 1;
}
}
if (ptr->flags & ESTR_meta)
x = expand_meta(buffer, ptr->unexpanded, sizeof buffer);
else
x = expand_env(buffer, ptr->unexpanded, sizeof buffer);
if (x != 0) {
lib_error(CATGETS(elm_msg_cat, ElmSet,
ElmBadVariableInElmrc,
"Bad variable on key \"%s\" value \"%s\""),
fieldname,val);
return 0;
}
estr_set_expanded(ptr,buffer);
return 1;
}
/* Retuns 1 if sepecial value "none" */
int dt_estr_is_disabled(ptr)
struct dt_estr_info *ptr;
{
if (ptr->flags & ESTR_none) {
if (0 == strcmp("none",ptr->unexpanded)) {
return 1;
}
}
return 0;
}
char * give_dt_estr_as_str(ptr,fieldname)
struct dt_estr_info *ptr;
char * fieldname;
{
if (!ptr->expanded && ptr->unexpanded)
expand_dt_estr(ptr,fieldname,ptr->unexpanded);
return ptr->expanded;
}
/* Set initial value */
extern void set_dt_estr(ptr, const_val, def_env)
struct dt_estr_info *ptr;
CONST char *const_val;
char *def_env;
{
char *cp;
if (def_env &&
(cp = getenv(def_env)) &&
cp[0]) {
char *x = elm_message(FRM("$%s"),def_env);
ptr->unexpanded = strmcpy(ptr->unexpanded,x);
estr_set_expanded(ptr,cp);
free(x);
} else {
if (ptr->flags & ESTR_none) {
if (0 == strcmp("none",const_val)) {
ptr->unexpanded = strmcpy(ptr->unexpanded,const_val);
if (ptr->expanded)
free(ptr->expanded);
ptr->expanded = NULL;
return;
}
}
if (ptr->flags & ESTR_metamail) {
if (0 == strcmp("metamail",const_val)) {
ptr->unexpanded = strmcpy(ptr->unexpanded,const_val);
metamail_expand(ptr);
return;
}
}
ptr->unexpanded = strmcpy(ptr->unexpanded,const_val);
estr_set_expanded(ptr,const_val);
}
}
#ifdef ANSI_C
static rc_parse_line dt_ESTR_parse_line;
#endif
static int dt_ESTR_parse_line(r,lcl,value,lineno,filename, negate)
struct rc_save_info_rec *r;
int lcl;
char *value;
int lineno;
char *filename;
int negate;
{
if (negate) {
lib_error(CATGETS(elm_msg_cat, ElmSet, ElmBadNegate,
"!%s is not supported in line %d in \"%s\" file"),
r->name,lineno,filename);
return 0;
}
r->val.estr->unexpanded = strmcpy(r->val.estr->unexpanded,value);
/* Free old value */
if (r->val.estr->expanded) {
free(r->val.estr->expanded);
r->val.estr->expanded = NULL;
}
return 1;
}
#if ANSI_C
static rc_get_value dt_ESTR_get_value;
#endif
static char * dt_ESTR_get_value(r)
struct rc_save_info_rec *r;
{
return r->val.estr->unexpanded;
}
#if ANSI_C
static rc_print_value dt_ESTR_print_value;
#endif
static void dt_ESTR_print_value(F,r,comment)
FILE *F;
struct rc_save_info_rec *r;
int comment;
{
if (r->val.estr->unexpanded) {
if (comment)
fprintf(F, "### ");
fprintf(F, "%s = %s\n", r->name, r->val.estr->unexpanded);
} else {
fprintf(F, "### %s (not set)\n", r->name);
}
}
struct rc_type rc_DT_ESTR = { RCTYPE_magic,
dt_ESTR_parse_line, BAD_parse_cline,
dt_ESTR_print_value, dt_ESTR_get_value };
int give_dt_enumerate_as_int(ptr)
struct dt_enumerate_info *ptr;
{
return ptr->val;
}
CONST char * give_dt_enumerate_as_str(ptr)
struct dt_enumerate_info *ptr;
{
static char * buffer = NULL;
if (ptr->val >= 0 &&
ptr->val < ptr->nlen)
return ptr->list[ptr->val];
if (buffer)
free(buffer);
buffer = elm_message(FRM("%d"), ptr->val);
return buffer;
}
int set_dt_enumerate_as_str(ptr,str)
struct dt_enumerate_info *ptr;
char *str;
{
int ci = -1, i;
int e_val;
e_val = 0; /* First value is 'unknown' */
for (i = 0; i < ptr->nlen; i++)
if (0 == strcmp(ptr->list[i],str)) {
e_val = i;
break;
} else if (0 == istrcmp(ptr->list[i],str))
ci = i;
if (!e_val && ci >= 0)
e_val = ci;
if (i == ptr->nlen) {
char *p;
if ((e_val = strtol(str,&p,10)) < 0 || *p != '\0')
return 0;
}
ptr->val = e_val;
return 1;
}
#ifdef ANSI_C
static rc_parse_line dt_ENUM_parse_line;
#endif
static int dt_ENUM_parse_line(r,lcl,value,lineno,filename, negate)
struct rc_save_info_rec *r;
int lcl;
char *value;
int lineno;
char *filename;
int negate;
{
if (negate) {
lib_error(CATGETS(elm_msg_cat, ElmSet, ElmBadNegate,
"!%s is not supported in line %d in \"%s\" file"),
r->name,lineno,filename);
return 0;
}
if (!set_dt_enumerate_as_str(r->val.enumerate,value)) {
int i;
lib_error(CATGETS(elm_msg_cat, ElmSet, ElmBadEKeyInElmrc,
"I can't understand %s key \"%s\" in line %d in \"%s\" file"),
r->name,value, lineno,filename);
lib_error(CATGETS(elm_msg_cat, ElmSet, ElmBadEKeyValues,
"Possible values are:"));
for (i = 0; i < r->val.enumerate->nlen; i++)
lib_error(FRM(" - %s"),
r->val.enumerate->list[i]);
return 0;
}
return 1;
}
#if ANSI_C
static rc_get_value dt_ENUM_get_value;
#endif
static char * dt_ENUM_get_value(r)
struct rc_save_info_rec *r;
{
static char * buffer = NULL;
if (r->val.enumerate->val >= 0 &&
r->val.enumerate->val < r->val.enumerate->nlen)
return r->val.enumerate->list[r->val.enumerate->val];
if (buffer)
free(buffer);
buffer = elm_message(FRM("%d"), r->val.enumerate->val);
return buffer;
}
#if ANSI_C
static rc_print_value dt_ENUM_print_value;
#endif
static void dt_ENUM_print_value(F,r,comment)
FILE *F;
struct rc_save_info_rec *r;
int comment;
{
if (comment)
fprintf(F, "### ");
if (r->val.enumerate->val >= 0 &&
r->val.enumerate->val < r->val.enumerate->nlen) {
char * s = r->val.enumerate->list[r->val.enumerate->val];
fprintf(F, "%s = %s\n", r->name, s);
DPRINT(Debug,9,(&Debug,
" option \"%s\", value=\"%s\"\n",
r->name,s ));
} else {
fprintf(F, "%s = %d\n", r->name,
r->val.enumerate->val);
DPRINT(Debug,9,(&Debug,
" option \"%s\", value=%d\n",
r->name,r->val.enumerate->val ));
}
}
struct rc_type rc_DT_ENUM = { RCTYPE_magic,
dt_ENUM_parse_line, BAD_parse_cline,
dt_ENUM_print_value, dt_ENUM_get_value };
/*
* Local Variables:
* mode:c
* c-basic-offset:4
* buffer-file-coding-system: iso-8859-1
* End:
*/
syntax highlighted by Code2HTML, v. 0.9.1