xref: /plan9-contrib/sys/src/cmd/upas/alias/aliasmail.c (revision 219b2ee8daee37f4aad58d63f21287faa8e4ffdc)
13e12c5d1SDavid du Colombier #include "common.h"
23e12c5d1SDavid du Colombier 
3*219b2ee8SDavid du Colombier /*
4*219b2ee8SDavid du Colombier  *  WARNING!  This turns all upper case names into lower case
5*219b2ee8SDavid du Colombier  *  local ones.
6*219b2ee8SDavid du Colombier  */
7*219b2ee8SDavid du Colombier 
83e12c5d1SDavid du Colombier /* predeclared */
93e12c5d1SDavid du Colombier static String	*getdbfiles(void);
103e12c5d1SDavid du Colombier static int	translate(char*, char*, String*, String*);
113e12c5d1SDavid du Colombier static int	lookup(char*, String*, 	String*, String*);
123e12c5d1SDavid du Colombier static int	compare(String*, char*);
13*219b2ee8SDavid du Colombier static char*	mklower(char*);
143e12c5d1SDavid du Colombier 
153e12c5d1SDavid du Colombier static int debug;
163e12c5d1SDavid du Colombier #define DEBUG if(debug)
173e12c5d1SDavid du Colombier 
183e12c5d1SDavid du Colombier /* loop through the names to be translated */
193e12c5d1SDavid du Colombier void
203e12c5d1SDavid du Colombier main(int argc, char *argv[])
213e12c5d1SDavid du Colombier {
223e12c5d1SDavid du Colombier 	String *alias;		/* the alias for the name */
233e12c5d1SDavid du Colombier 	char *thissys;		/* name of this system */
243e12c5d1SDavid du Colombier 	String *files;		/* list of files to search */
253e12c5d1SDavid du Colombier 	int i, rv;
263e12c5d1SDavid du Colombier 
273e12c5d1SDavid du Colombier 	ARGBEGIN {
283e12c5d1SDavid du Colombier 	case 'd':
293e12c5d1SDavid du Colombier 		debug = 1;
303e12c5d1SDavid du Colombier 		break;
313e12c5d1SDavid du Colombier 	} ARGEND
323e12c5d1SDavid du Colombier 	if (chdir(MAILROOT) < 0) {
333e12c5d1SDavid du Colombier 		perror("translate(chdir):");
343e12c5d1SDavid du Colombier 		exit(1);
353e12c5d1SDavid du Colombier 	}
363e12c5d1SDavid du Colombier 	if (chdir("lib") < 0) {
373e12c5d1SDavid du Colombier 		perror("translate(chdir):");
383e12c5d1SDavid du Colombier 		exit(1);
393e12c5d1SDavid du Colombier 	}
403e12c5d1SDavid du Colombier 
413e12c5d1SDavid du Colombier 	/* get environmental info */
423e12c5d1SDavid du Colombier 	thissys = sysname_read();
433e12c5d1SDavid du Colombier 	files = getdbfiles();
443e12c5d1SDavid du Colombier 	alias = s_new();
453e12c5d1SDavid du Colombier 
463e12c5d1SDavid du Colombier 	/* loop through the names to be translated (from standard input) */
473e12c5d1SDavid du Colombier 	for(i=0; i<argc; i++) {
48*219b2ee8SDavid du Colombier 		mklower(argv[i]);
493e12c5d1SDavid du Colombier 		rv = translate(argv[i], thissys, files, alias);
503e12c5d1SDavid du Colombier 		if (rv < 0 || *s_to_c(alias) == '\0')
513e12c5d1SDavid du Colombier 			print("local!%s\n", argv[i]);
523e12c5d1SDavid du Colombier 		else
533e12c5d1SDavid du Colombier 			print("%s\n", s_to_c(alias));
543e12c5d1SDavid du Colombier 	}
553e12c5d1SDavid du Colombier 	exits(0);
563e12c5d1SDavid du Colombier }
573e12c5d1SDavid du Colombier 
583e12c5d1SDavid du Colombier /* get the list of dbfiles to search */
593e12c5d1SDavid du Colombier static String *
603e12c5d1SDavid du Colombier getdbfiles(void)
613e12c5d1SDavid du Colombier {
623e12c5d1SDavid du Colombier 	Biobuf *fp;
633e12c5d1SDavid du Colombier 	String *files = s_new();
643e12c5d1SDavid du Colombier 
653e12c5d1SDavid du Colombier 	/* system wide aliases */
663e12c5d1SDavid du Colombier 	if ((fp = sysopen("namefiles", "r", 0)) != 0){
673e12c5d1SDavid du Colombier 		while(s_getline(fp, files))
683e12c5d1SDavid du Colombier 			s_append(files, " ");
693e12c5d1SDavid du Colombier 		sysclose(fp);
703e12c5d1SDavid du Colombier 	}
713e12c5d1SDavid du Colombier 
723e12c5d1SDavid du Colombier 
733e12c5d1SDavid du Colombier 	DEBUG print("files are %s\n", s_to_c(files));
743e12c5d1SDavid du Colombier 
753e12c5d1SDavid du Colombier 	return files;
763e12c5d1SDavid du Colombier }
773e12c5d1SDavid du Colombier 
783e12c5d1SDavid du Colombier /* loop through the translation files */
793e12c5d1SDavid du Colombier static int
803e12c5d1SDavid du Colombier translate(char *name,		/* name to translate */
813e12c5d1SDavid du Colombier 	char *thissys,		/* name of this system */
823e12c5d1SDavid du Colombier 	String *files,
833e12c5d1SDavid du Colombier 	String *alias)		/* where to put the alias */
843e12c5d1SDavid du Colombier {
853e12c5d1SDavid du Colombier 	String *file = s_new();
863e12c5d1SDavid du Colombier 	String *fullname;
873e12c5d1SDavid du Colombier 	char *user;
883e12c5d1SDavid du Colombier 
893e12c5d1SDavid du Colombier 	DEBUG print("translate(%s, %s, %s, %s)\n", name, thissys,
903e12c5d1SDavid du Colombier 		s_to_c(files), s_to_c(alias));
913e12c5d1SDavid du Colombier 
923e12c5d1SDavid du Colombier 	/* create the full name to avoid loops (system!name) */
933e12c5d1SDavid du Colombier 	fullname = s_copy(thissys);
943e12c5d1SDavid du Colombier 	s_append(fullname, "!");
953e12c5d1SDavid du Colombier 	s_append(fullname, name);
963e12c5d1SDavid du Colombier 
973e12c5d1SDavid du Colombier 	/* look at user's local names */
983e12c5d1SDavid du Colombier 	user = getlog();
993e12c5d1SDavid du Colombier 	if (user != 0) {
1003e12c5d1SDavid du Colombier 		mboxpath("names", user, s_restart(file), 0);
1013e12c5d1SDavid du Colombier 		if (lookup(name, fullname, file, alias)==0) {
1023e12c5d1SDavid du Colombier 			s_free(fullname);
1033e12c5d1SDavid du Colombier 			s_free(file);
1043e12c5d1SDavid du Colombier 			return 0;
1053e12c5d1SDavid du Colombier 		}
1063e12c5d1SDavid du Colombier 	}
1073e12c5d1SDavid du Colombier 
1083e12c5d1SDavid du Colombier 	/* look at system-wide names */
1093e12c5d1SDavid du Colombier 	s_restart(files);
1103e12c5d1SDavid du Colombier 	while (s_parse(files, s_restart(file)) != 0) {
1113e12c5d1SDavid du Colombier 		if (lookup(name, fullname, file, alias)==0) {
1123e12c5d1SDavid du Colombier 			s_free(fullname);
1133e12c5d1SDavid du Colombier 			s_free(file);
1143e12c5d1SDavid du Colombier 			return 0;
1153e12c5d1SDavid du Colombier 		}
1163e12c5d1SDavid du Colombier 	}
1173e12c5d1SDavid du Colombier 
1183e12c5d1SDavid du Colombier 	return -1;
1193e12c5d1SDavid du Colombier }
1203e12c5d1SDavid du Colombier 
1213e12c5d1SDavid du Colombier /*  Loop through the entries in a translation file looking for a match.
1223e12c5d1SDavid du Colombier  *  Return 0 if found, -1 otherwise.
1233e12c5d1SDavid du Colombier  */
1243e12c5d1SDavid du Colombier static int
1253e12c5d1SDavid du Colombier lookup(	char *name,
1263e12c5d1SDavid du Colombier 	String *fullname,
1273e12c5d1SDavid du Colombier 	String *file,
1283e12c5d1SDavid du Colombier 	String *alias)	/* returned String */
1293e12c5d1SDavid du Colombier {
1303e12c5d1SDavid du Colombier 	Biobuf *fp;
1313e12c5d1SDavid du Colombier 	String *line = s_new();
1323e12c5d1SDavid du Colombier 	String *token = s_new();
1333e12c5d1SDavid du Colombier 	int rv = -1;
1343e12c5d1SDavid du Colombier 
1353e12c5d1SDavid du Colombier 	DEBUG print("lookup(%s, %s, %s, %s)\n", name, s_to_c(fullname),
1363e12c5d1SDavid du Colombier 		s_to_c(file), s_to_c(alias));
1373e12c5d1SDavid du Colombier 
1383e12c5d1SDavid du Colombier 	s_reset(alias);
1393e12c5d1SDavid du Colombier 	if ((fp = sysopen(s_to_c(file), "r", 0)) == 0)
1403e12c5d1SDavid du Colombier 		return -1;
1413e12c5d1SDavid du Colombier 
1423e12c5d1SDavid du Colombier 	/* look for a match */
1433e12c5d1SDavid du Colombier 	while (s_getline(fp, s_restart(line))!=0) {
1443e12c5d1SDavid du Colombier 		DEBUG print("line is %s\n", s_to_c(line));
1453e12c5d1SDavid du Colombier 		s_restart(token);
1463e12c5d1SDavid du Colombier 		if (s_parse(s_restart(line), token)==0)
1473e12c5d1SDavid du Colombier 			continue;
1483e12c5d1SDavid du Colombier 		if (compare(token, name)!=0)
1493e12c5d1SDavid du Colombier 			continue;
1503e12c5d1SDavid du Colombier 		/* match found, get the alias */
1513e12c5d1SDavid du Colombier 		while(s_parse(line, s_restart(token))!=0) {
1523e12c5d1SDavid du Colombier 			/* avoid definition loops */
1533e12c5d1SDavid du Colombier 			if (compare(token, name)==0 ||
1543e12c5d1SDavid du Colombier 			    compare(token, s_to_c(fullname))==0){
1553e12c5d1SDavid du Colombier 				s_append(alias, "local");
1563e12c5d1SDavid du Colombier 				s_append(alias, "!");
1573e12c5d1SDavid du Colombier 				s_append(alias, name);
1583e12c5d1SDavid du Colombier 			} else {
1593e12c5d1SDavid du Colombier 				s_append(alias, s_to_c(token));
1603e12c5d1SDavid du Colombier 			}
1613e12c5d1SDavid du Colombier 			s_append(alias, " ");
1623e12c5d1SDavid du Colombier 		}
1633e12c5d1SDavid du Colombier 		rv = 0;
1643e12c5d1SDavid du Colombier 		break;
1653e12c5d1SDavid du Colombier 	}
1663e12c5d1SDavid du Colombier 	s_free(line);
1673e12c5d1SDavid du Colombier 	s_free(token);
1683e12c5d1SDavid du Colombier 	sysclose(fp);
1693e12c5d1SDavid du Colombier 	return rv;
1703e12c5d1SDavid du Colombier }
1713e12c5d1SDavid du Colombier 
1723e12c5d1SDavid du Colombier #define lower(c) ((c)>='A' && (c)<='Z' ? (c)-('A'-'a'):(c))
173*219b2ee8SDavid du Colombier 
174*219b2ee8SDavid du Colombier /* compare two Strings (case insensitive) */
1753e12c5d1SDavid du Colombier static int
1763e12c5d1SDavid du Colombier compare(String *s1,
1773e12c5d1SDavid du Colombier 	char *p2)
1783e12c5d1SDavid du Colombier {
1793e12c5d1SDavid du Colombier 	char *p1 = s_to_c(s1);
1803e12c5d1SDavid du Colombier 	int rv;
1813e12c5d1SDavid du Colombier 
1823e12c5d1SDavid du Colombier 	DEBUG print("comparing %s to %s\n", p1, p2);
1833e12c5d1SDavid du Colombier 	while((rv = lower(*p1) - lower(*p2)) == 0) {
1843e12c5d1SDavid du Colombier 		if (*p1 == '\0')
1853e12c5d1SDavid du Colombier 			break;
1863e12c5d1SDavid du Colombier 		p1++;
1873e12c5d1SDavid du Colombier 		p2++;
1883e12c5d1SDavid du Colombier 	}
1893e12c5d1SDavid du Colombier 	return rv;
1903e12c5d1SDavid du Colombier }
191*219b2ee8SDavid du Colombier 
192*219b2ee8SDavid du Colombier char*
193*219b2ee8SDavid du Colombier mklower(char *name)
194*219b2ee8SDavid du Colombier {
195*219b2ee8SDavid du Colombier 	char *p;
196*219b2ee8SDavid du Colombier 	char c;
197*219b2ee8SDavid du Colombier 
198*219b2ee8SDavid du Colombier 	for(p = name; *p; p++){
199*219b2ee8SDavid du Colombier 		c = *p;
200*219b2ee8SDavid du Colombier 		*p = lower(c);
201*219b2ee8SDavid du Colombier 	}
202*219b2ee8SDavid du Colombier 	return name;
203*219b2ee8SDavid du Colombier }
204