static char rcsid[] = "@(#)$Id: expand.c,v 1.22 2006/05/30 16:33:21 hurtta Exp $";
/******************************************************************************
* The Elm (ME+) Mail System - $Revision: 1.22 $ $State: Exp $
*
* Modified by: Kari Hurtta <hurtta+elm@posti.FMI.FI>
* (was hurtta+elm@ozone.FMI.FI)
******************************************************************************
* The Elm Mail System
*
* Copyright (c) 1988-1992 USENET Community Trust
* Copyright (c) 1986,1987 Dave Taylor
*****************************************************************************/
/** This is a library routine for the various utilities that allows
users to have the standard 'Elm' folder directory nomenclature
for all filenames (e.g. '+', '=' or '%'). It should be compiled
and then linked in as needed.
**/
#include <stdio.h>
#include "headers.h"
#include "s_elmrc.h"
DEBUG_VAR(Debug,__FILE__,"config");
extern nl_catd elm_msg_cat; /* message catalog */
int expand(filename, size)
char *filename;
int size;
{
if (filename[0] == '+' || filename[0] == '%' || filename[0] == '=') {
char buffer[SLEN];
/* give_dt_estr_as_str adds / to end */
char * str = give_dt_estr_as_str(&folders_e,"maildir");
if (!str)
return 0;
strfcpy(buffer,str, sizeof buffer);
strfcat(buffer,filename+1, sizeof buffer);
strfcpy(filename, buffer, size);
}
return 1;
}
/* Returns 0 if no expansion done
1 if expansion done
-1 on failure
*/
int expand_path(dest, src, destlen)
char *dest; /* pointer to space to hold the result */
CONST char *src; /* pointer to string to expand */
unsigned destlen; /* size of the destination buffer */
{
CONST char *src0 = src;
char *dest0 = dest;
int check_for_env = TRUE;
int ret = 0; /* assume success */
if (destlen < 1) {
DPRINT(Debug,1,(&Debug,
"expand_path()=-1, src=%s, destlen=%d\n",
src,destlen));
return -1;
}
--destlen; /* reserve space for trailing '\0' */
/*
* Copy through the rest, performing $NAME expansion where appropriate.
*/
while (destlen > 0 && *src != '\0') {
/*
* Check for "$NAME" at the start of every path component.
*/
if (check_for_env && *src == '$') {
/*
* Get the environment parameter name into "envname_buf"
* and advance "src" to the next path component.
*/
CONST char *envname_front = ++src;
CONST char *expval;
int len, p;
char envname_buf[SLEN];
if ((len = strcspn(src, "/@")) == 0)
len = strlen(src);
src += len;
strnfcpy(envname_buf, envname_front, len,
sizeof(envname_buf),NULL);
/*
* Copy over the environment expansion. If the environment
* parameter is undefined then copy over unchanged and set
* a fail return status.
*/
if ((expval = getenv(envname_buf)) == NULL) {
*dest++ = '$';
--destlen;
expval = envname_buf;
ret = -1;
DPRINT(Debug,5,(&Debug,
"getenv(%s) FAILED\n",envname_buf));
} else {
DPRINT(Debug,61,(&Debug,
"getenv(%s)=%s\n",
envname_buf,expval));
}
len = strlen(expval);
strnfcpy(dest, expval, len, destlen,&p);
dest += p;
destlen -= p;
check_for_env = FALSE;
if (0 == ret)
ret = 1;
} else {
check_for_env = (*src == '/');
*dest++ = *src++;
--destlen;
}
}
*dest = '\0';
if (destlen <= 0)
ret = -1;
DPRINT(Debug,(ret == 0 ? 11: 5),(&Debug,
"expand_path()=%d, src=%s, dest=%s\n",
ret,src0,dest0));
return ret;
}
int expand_meta(dest, src, destlen)
char *dest; /* pointer to space to hold the result */
CONST char *src; /* pointer to string to expand */
unsigned destlen; /* size of the destination buffer */
{
CONST char *src0 = src;
char *dest0 = dest;
CONST char * c;
int ret = 0;
if (destlen < 1) {
DPRINT(Debug,1,(&Debug,
"expand_meta()=-1, src=%s, destlen=%d\n",
src,destlen));
return -1;
}
--destlen; /* reserve space for trailing '\0' */
if (src[0] == '+' || src[0] == '%' || src[0] == '=') {
CONST char * expval;
int len,p;
/* give_dt_estr_as_str adds / to end */
char * str = give_dt_estr_as_str(&folders_e,"maildir");
if (!str) {
expval = "=";
ret = -1;
len = 1;
} else {
expval = str;
len = strlen(str);
}
strnfcpy(dest, expval, len, destlen,&p);
dest += p;
destlen -= p;
++src;
if ('/' == src[0] && str)
src++;
if (expand_path(dest,src,destlen+1) < 0)
ret = -1;
} else if (src[0] == '{' && NULL != (c = strpbrk(src,"}/")) &&
*c == '}' && *(c+1) == '/') {
int l = (c - src) + 1;
char result[STRING];
int len,p;
if (home[0] != '\0' && 4 == l && 0 == strncmp(src,"{rc}",l)) {
len = elm_sfprintf(result, sizeof result,
FRM("%s/.elm"),home);
src += l;
} else if (5 == l && 0 == strncmp(src,"{lib}",l)) {
len = elm_sfprintf(result, sizeof result,
FRM("%s"),LIBHOME);
src += l;
} else if (5 == l && 0 == strncmp(src,"{etc}",l)) {
len = elm_sfprintf(result, sizeof result,
FRM("%s"),ETCHOME);
src += l;
} else if (5 == l && 0 == strncmp(src,"{bin}",l)) {
len = elm_sfprintf(result, sizeof result,
FRM("%s"),BINHOME);
src += l;
} else if (5 == l && 0 == strncmp(src,"{doc}",l)) {
char * attachment_dir_val =
give_dt_estr_as_str(&attachment_dir_e,
"attachment-dir");
if (!attachment_dir_val)
attachment_dir_val = "";
len = elm_sfprintf(result, sizeof result,
FRM("%s"),attachment_dir_val);
src += l;
if (!attachment_dir_val[0]) {
DPRINT(Debug,3,(&Debug,
"expand_meta: {doc} aka attachment-dir is not set\n"));
ret = -1;
}
} else {
strnfcpy(result,src,l,sizeof result,NULL);
len = l;
ret = -1;
}
strnfcpy(dest, result, len, destlen,&p);
dest += p;
destlen -= p;
if (expand_path(dest,src,destlen+1) < 0)
ret = -1;
} else {
if (expand_env(dest,src,destlen+1) < 0)
ret = -1;
}
DPRINT(Debug,(ret == 0 ? 10: 1),(&Debug,
"expand_meta()=%d, src=%s, dest=%s\n",
ret,src0,dest0));
return ret;
}
/*
* expand_env() - Perform environment expansion on a pathname. Also
* replaces "~" at the front of the path with the user's home directory.
* Environment expansion occurs at the path component boundaries, e.g.
* "/foo/$BAR/baz" is subject to expansion but "/foo/zzz$BAR/baz" is not.
* Returns 0 if expansion successful, -1 if an error occurs (result too
* long, cannot get home directory, or environment expansion failed).
*/
int expand_env(dest, src, destlen)
char *dest; /* pointer to space to hold the result */
CONST char *src; /* pointer to string to expand */
unsigned destlen; /* size of the destination buffer */
{
int ret = 0; /* assume success */
CONST char *src0 = src;
if (destlen < 1) {
DPRINT(Debug,1,(&Debug,
"expand_env()=-1, src=%s, destlen=%d",
src,destlen));
return -1;
}
--destlen; /* reserve space for trailing '\0' */
/*
* Replace "~" at front with user's home directory.
*/
if (src[0] == '~' && (src[1] == '\0' || src[1] == '/')) {
CONST char *expval;
int len, p;
if (home[0] == '\0') {
expval = "~";
ret = -1;
} else {
expval = home;
}
if ((len = strlen(expval)) > destlen)
len = destlen;
strnfcpy(dest, expval, len, destlen, &p);
dest += p;
destlen -= p;
++src;
}
if (expand_path(dest,src,destlen+1) < 0)
ret = -1;
DPRINT(Debug,(ret == 0 ? 12: 4),(&Debug,
"expand_env()=%d, src=%s, dest=%s\n",
ret,src0,dest));
return ret;
}
/*
* Local Variables:
* mode:c
* c-basic-offset:4
* buffer-file-coding-system: iso-8859-1
* End:
*/
syntax highlighted by Code2HTML, v. 0.9.1