Thanks to John Cummings.
This commit is contained in:
parent
9f1fdc1287
commit
d1f529f46f
27 changed files with 4344 additions and 0 deletions
281
src/cmd/upas/alias/aliasmail.c
Normal file
281
src/cmd/upas/alias/aliasmail.c
Normal file
|
|
@ -0,0 +1,281 @@
|
|||
#include "common.h"
|
||||
|
||||
/*
|
||||
* WARNING! This turns all upper case names into lower case
|
||||
* local ones.
|
||||
*/
|
||||
|
||||
/* predeclared */
|
||||
static String *getdbfiles(void);
|
||||
static int translate(char*, char**, String*, String*);
|
||||
static int lookup(String**, String*, String*);
|
||||
static int compare(String*, char*);
|
||||
static char* mklower(char*);
|
||||
|
||||
static int debug;
|
||||
static int from;
|
||||
static char *namefiles = "namefiles";
|
||||
#define DEBUG if(debug)
|
||||
|
||||
/* loop through the names to be translated */
|
||||
void
|
||||
main(int argc, char *argv[])
|
||||
{
|
||||
String *s;
|
||||
String *alias; /* the alias for the name */
|
||||
char **names; /* names of this system */
|
||||
String *files; /* list of files to search */
|
||||
int i, rv;
|
||||
char *p;
|
||||
|
||||
ARGBEGIN {
|
||||
case 'd':
|
||||
debug = 1;
|
||||
break;
|
||||
case 'f':
|
||||
from = 1;
|
||||
break;
|
||||
case 'n':
|
||||
namefiles = ARGF();
|
||||
break;
|
||||
} ARGEND
|
||||
if (chdir(unsharp(UPASLIB)) < 0) {
|
||||
perror("translate(chdir):");
|
||||
exit9(1);
|
||||
}
|
||||
|
||||
/* get environmental info */
|
||||
names = sysnames_read();
|
||||
files = getdbfiles();
|
||||
alias = s_new();
|
||||
|
||||
/* loop through the names to be translated (from standard input) */
|
||||
for(i=0; i<argc; i++) {
|
||||
s = unescapespecial(s_copy(mklower(argv[i])));
|
||||
if(strchr(s_to_c(s), '!') == 0)
|
||||
rv = translate(s_to_c(s), names, files, alias);
|
||||
else
|
||||
rv = -1;
|
||||
if(from){
|
||||
if (rv >= 0 && *s_to_c(alias) != '\0'){
|
||||
p = strchr(s_to_c(alias), '\n');
|
||||
if(p)
|
||||
*p = 0;
|
||||
p = strchr(s_to_c(alias), '!');
|
||||
if(p) {
|
||||
*p = 0;
|
||||
print("%s", s_to_c(alias));
|
||||
} else {
|
||||
p = strchr(s_to_c(alias), '@');
|
||||
if(p)
|
||||
print("%s", p+1);
|
||||
else
|
||||
print("%s", s_to_c(alias));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (rv < 0 || *s_to_c(alias) == '\0')
|
||||
print("local!%s\n", s_to_c(s));
|
||||
else {
|
||||
/* this must be a write, not a print */
|
||||
write(1, s_to_c(alias), strlen(s_to_c(alias)));
|
||||
}
|
||||
}
|
||||
s_free(s);
|
||||
}
|
||||
exits(0);
|
||||
}
|
||||
|
||||
/* get the list of dbfiles to search */
|
||||
static String *
|
||||
getdbfiles(void)
|
||||
{
|
||||
Sinstack *sp;
|
||||
String *files = s_new();
|
||||
char *nf;
|
||||
|
||||
if(from)
|
||||
nf = "fromfiles";
|
||||
else
|
||||
nf = namefiles;
|
||||
|
||||
/* system wide aliases */
|
||||
if ((sp = s_allocinstack(nf)) != 0){
|
||||
while(s_rdinstack(sp, files))
|
||||
s_append(files, " ");
|
||||
s_freeinstack(sp);
|
||||
}
|
||||
|
||||
|
||||
DEBUG print("files are %s\n", s_to_c(files));
|
||||
|
||||
return files;
|
||||
}
|
||||
|
||||
/* loop through the translation files */
|
||||
static int
|
||||
translate(char *name, /* name to translate */
|
||||
char **namev, /* names of this system */
|
||||
String *files, /* names of system alias files */
|
||||
String *alias) /* where to put the alias */
|
||||
{
|
||||
String *file = s_new();
|
||||
String **fullnamev;
|
||||
int n, rv;
|
||||
|
||||
rv = -1;
|
||||
|
||||
DEBUG print("translate(%s, %s, %s)\n", name,
|
||||
s_to_c(files), s_to_c(alias));
|
||||
|
||||
/* create the full name to avoid loops (system!name) */
|
||||
for(n = 0; namev[n]; n++)
|
||||
;
|
||||
fullnamev = (String**)malloc(sizeof(String*)*(n+2));
|
||||
n = 0;
|
||||
fullnamev[n++] = s_copy(name);
|
||||
for(; *namev; namev++){
|
||||
fullnamev[n] = s_copy(*namev);
|
||||
s_append(fullnamev[n], "!");
|
||||
s_append(fullnamev[n], name);
|
||||
n++;
|
||||
}
|
||||
fullnamev[n] = 0;
|
||||
|
||||
/* look at system-wide names */
|
||||
s_restart(files);
|
||||
while (s_parse(files, s_restart(file)) != 0) {
|
||||
if (lookup(fullnamev, file, alias)==0) {
|
||||
rv = 0;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
out:
|
||||
for(n = 0; fullnamev[n]; n++)
|
||||
s_free(fullnamev[n]);
|
||||
s_free(file);
|
||||
free(fullnamev);
|
||||
return rv;
|
||||
}
|
||||
|
||||
/*
|
||||
* very dumb conversion to bang format
|
||||
*/
|
||||
static String*
|
||||
attobang(String *token)
|
||||
{
|
||||
char *p;
|
||||
String *tok;
|
||||
|
||||
p = strchr(s_to_c(token), '@');
|
||||
if(p == 0)
|
||||
return token;
|
||||
|
||||
p++;
|
||||
tok = s_copy(p);
|
||||
s_append(tok, "!");
|
||||
s_nappend(tok, s_to_c(token), p - s_to_c(token) - 1);
|
||||
|
||||
return tok;
|
||||
}
|
||||
|
||||
/* Loop through the entries in a translation file looking for a match.
|
||||
* Return 0 if found, -1 otherwise.
|
||||
*/
|
||||
static int
|
||||
lookup(
|
||||
String **namev,
|
||||
String *file,
|
||||
String *alias) /* returned String */
|
||||
{
|
||||
String *line = s_new();
|
||||
String *token = s_new();
|
||||
String *bangtoken;
|
||||
int i, rv = -1;
|
||||
char *name = s_to_c(namev[0]);
|
||||
Sinstack *sp;
|
||||
|
||||
DEBUG print("lookup(%s, %s, %s, %s)\n", s_to_c(namev[0]), s_to_c(namev[1]),
|
||||
s_to_c(file), s_to_c(alias));
|
||||
|
||||
s_reset(alias);
|
||||
if ((sp = s_allocinstack(s_to_c(file))) == 0)
|
||||
return -1;
|
||||
|
||||
/* look for a match */
|
||||
while (s_rdinstack(sp, s_restart(line))!=0) {
|
||||
DEBUG print("line is %s\n", s_to_c(line));
|
||||
s_restart(token);
|
||||
if (s_parse(s_restart(line), token)==0)
|
||||
continue;
|
||||
if (compare(token, "#include")==0){
|
||||
if(s_parse(line, s_restart(token))!=0) {
|
||||
if(lookup(namev, line, alias) == 0)
|
||||
break;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if (compare(token, name)!=0)
|
||||
continue;
|
||||
/* match found, get the alias */
|
||||
while(s_parse(line, s_restart(token))!=0) {
|
||||
bangtoken = attobang(token);
|
||||
|
||||
/* avoid definition loops */
|
||||
for(i = 0; namev[i]; i++)
|
||||
if(compare(bangtoken, s_to_c(namev[i]))==0) {
|
||||
s_append(alias, "local");
|
||||
s_append(alias, "!");
|
||||
s_append(alias, name);
|
||||
break;
|
||||
}
|
||||
|
||||
if(namev[i] == 0)
|
||||
s_append(alias, s_to_c(token));
|
||||
s_append(alias, "\n");
|
||||
|
||||
if(bangtoken != token)
|
||||
s_free(bangtoken);
|
||||
}
|
||||
rv = 0;
|
||||
break;
|
||||
}
|
||||
s_free(line);
|
||||
s_free(token);
|
||||
s_freeinstack(sp);
|
||||
return rv;
|
||||
}
|
||||
|
||||
#define lower(c) ((c)>='A' && (c)<='Z' ? (c)-('A'-'a'):(c))
|
||||
|
||||
/* compare two Strings (case insensitive) */
|
||||
static int
|
||||
compare(String *s1,
|
||||
char *p2)
|
||||
{
|
||||
char *p1 = s_to_c(s1);
|
||||
int rv;
|
||||
|
||||
DEBUG print("comparing %s to %s\n", p1, p2);
|
||||
while((rv = lower(*p1) - lower(*p2)) == 0) {
|
||||
if (*p1 == '\0')
|
||||
break;
|
||||
p1++;
|
||||
p2++;
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
static char*
|
||||
mklower(char *name)
|
||||
{
|
||||
char *p;
|
||||
char c;
|
||||
|
||||
for(p = name; *p; p++){
|
||||
c = *p;
|
||||
*p = lower(c);
|
||||
}
|
||||
return name;
|
||||
}
|
||||
21
src/cmd/upas/alias/mkfile
Normal file
21
src/cmd/upas/alias/mkfile
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
<$PLAN9/src/mkhdr
|
||||
|
||||
TARG=aliasmail
|
||||
|
||||
OFILES=aliasmail.$O\
|
||||
|
||||
LIB=../common/libcommon.a\
|
||||
|
||||
HFILES=../common/common.h\
|
||||
../common/sys.h\
|
||||
|
||||
|
||||
BIN=$PLAN9/bin/upas
|
||||
|
||||
UPDATE=\
|
||||
mkfile\
|
||||
$HFILES\
|
||||
${OFILES:%.$O=%.c}\
|
||||
|
||||
<$PLAN9/src/mkone
|
||||
CFLAGS=$CFLAGS -I../common
|
||||
Loading…
Add table
Add a link
Reference in a new issue