/* * CDDL HEADER START * * The contents of this file are subject to the terms of the * Common Development and Distribution License, Version 1.0 only * (the "License"). You may not use this file except in compliance * with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. * See the License for the specific language governing permissions * and limitations under the License. * * When distributing Covered Code, include this CDDL HEADER in each * file and include the License file at usr/src/OPENSOLARIS.LICENSE. * If applicable, add the following below this CDDL HEADER, with the * fields enclosed by brackets "[]" replaced with your own identifying * information: Portions Copyright [yyyy] [name of copyright owner] * * CDDL HEADER END */ /* * Copyright 2005 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ /* * mkmap - program to convert the mail.aliases map into an * inverse map of back to */ #include #include #include #include #include #include #include #include #include #include "ypdefs.h" USE_YP_PREFIX USE_YP_MASTER_NAME USE_YP_LAST_MODIFIED #define MKAL_INCLUDE ":include:" void CopyName(char *dst, char *src, int len); int HostCheck(char *h, char *a); void DoName(char *cp); void UpperCase(char *cp); void AddYPEntries(void); int Verbose = 0; /* to get the gory details */ int UucpOK = 0; /* pass all UUCP names right through */ int DomainOK = 0; /* pass all Domain names (with dots) */ int ErrorCheck = 0; /* check carefully for errors */ int NoOutput = 0; /* no output, just do the check */ int Simple = 0; /* Do not do the user name preference step */ int NameMode = 0; /* Try to capitalize as names */ DBM *Indbm = NULL, *Scandbm = NULL, *Outdbm = NULL; int IsMailingList(char *s) { /* * returns true if the given string is a mailing list */ char *p; if (strchr(s, ',')) return (1); if (strchr(s, '|')) return (1); p = strchr(s, ':'); if (p && strncmp(p, MKAL_INCLUDE, sizeof (MKAL_INCLUDE))) return (1); return (0); } int IsQualified(char *s, char *p, char *h) { /* * returns true if the given string is qualified with a host name */ register char *middle; middle = strchr(s, '@'); if (middle) { for (middle = s; *middle != '@'; *p++ = *middle++) continue; *p = '\0'; CopyName(h, middle+1, strlen(middle + 1)); return (1); } middle = strrchr(s, '!'); if (middle) { strcpy(p, middle+1); *middle = '\0'; CopyName(h, s, strlen(s)); *middle = '!'; return (1); } return (0); } int IsMaint(char *s) { /* * returns true if the given string is one of the maintenence * strings used in sendmail or NIS. */ if (*s == '@') return (1); if (strncmp(s, yp_prefix, yp_prefix_sz) == 0) return (1); return (0); } void CopyName(char *dst, char *src, int len) { /* * copy a string, but ignore white space */ while (*src && len--) { if (isspace(*src)) src++; else *dst++ = *src++; } *dst = '\0'; } int Compare(char *s1, char *s2) { /* * compare strings, but ignore white space */ while (*s1 != '\0' && isspace(*s1)) s1++; while (*s2 != '\0' && isspace(*s2)) s2++; return (strcmp(s1, s2)); } void ProcessMap(void) { datum key, value, part, partvalue; char address[PBLKSIZ]; /* qualified version */ char user[PBLKSIZ]; /* unqualified version */ char userpart[PBLKSIZ]; /* unqualified part of qualified addr. */ char hostpart[PBLKSIZ]; /* rest of qualified addr. */ for (key = dbm_firstkey(Scandbm); key.dptr != NULL; key = dbm_nextkey(Scandbm)) { value = dbm_fetch(Indbm, key); CopyName(address, value.dptr, value.dsize); CopyName(user, key.dptr, key.dsize); if (address == NULL) continue; if (IsMailingList(address)) continue; if (!IsQualified(address, userpart, hostpart)) continue; if (IsMaint(user)) continue; if (ErrorCheck && HostCheck(hostpart, address)) { printf("Invalid host %s in %s:%s\n", hostpart, user, address); continue; } part.dptr = userpart; part.dsize = strlen(userpart) + 1; if (Simple) partvalue.dptr = NULL; else partvalue = dbm_fetch(Indbm, part); value.dptr = address; value.dsize = strlen(address) + 1; if (partvalue.dptr != NULL && Compare(partvalue.dptr, user) == 0) { if (NameMode) DoName(userpart); if (!NoOutput) dbm_store(Outdbm, value, part, DBM_REPLACE); if (Verbose) printf("%s --> %s --> %s\n", userpart, user, address); } else { if (NameMode) DoName(user); key.dptr = user; key.dsize = strlen(user) + 1; if (!NoOutput) dbm_store(Outdbm, value, key, DBM_REPLACE); if (Verbose) printf("%s --> %s\n", user, address); } } } /* * Returns true if this is an invalid host */ int HostCheck(char *h, char *a) { struct hostent *hp; if (DomainOK && strchr(a, '.')) return (0); if (UucpOK && strchr(a, '!')) return (0); hp = gethostbyname(h); return (hp == NULL); } /* * Apply some Heurisitcs to upper case-ify the name * If it has a dot in it. */ void DoName(char *cp) { if (strchr(cp, '.') == NULL) return; while (*cp) { UpperCase(cp); while (*cp && *cp != '-' && *cp != '.') cp++; if (*cp) cp++; /* skip past punctuation */ } } /* * upper cases one name - stops at a . */ void UpperCase(char *cp) { int ch = cp[0]; if (isupper(ch)) ch = tolower(ch); if (ch == 'f' && cp[1] == 'f') return; /* handle ff */ if (ch == 'm' && cp[1] == 'c' && islower(cp[2])) cp[2] = toupper(cp[2]); if (islower(ch)) cp[0] = toupper(ch); } void AddYPEntries(void) { datum key, value; char last_modified[PBLKSIZ]; char host_name[PBLKSIZ]; time_t now; /* * Add the special NIS entries. */ key.dptr = yp_last_modified; key.dsize = yp_last_modified_sz; time(&now); sprintf(last_modified, "%10.10d", now); value.dptr = last_modified; value.dsize = strlen(value.dptr); dbm_store(Outdbm, key, value, DBM_REPLACE); key.dptr = yp_master_name; key.dsize = yp_master_name_sz; sysinfo(SI_HOSTNAME, host_name, sizeof (host_name)); value.dptr = host_name; value.dsize = strlen(value.dptr); dbm_store(Outdbm, key, value, DBM_REPLACE); } int main(int argc, char *argv[]) { while (argc > 1 && argv[1][0] == '-') { switch (argv[1][1]) { case 'v': Verbose = 1; break; case 'u': UucpOK = 1; break; case 'd': DomainOK = 1; break; case 'e': ErrorCheck = 1; break; case 's': Simple = 1; break; case 'n': NameMode = 1; break; default: printf("Unknown option %c\n", argv[1][1]); break; } argc--; argv++; } if (argc < 2) { printf("Usage: mkalias [-e] [-v] [-u] [-d] [-s] [-n] \n"); exit(1); } Indbm = dbm_open(argv[1], O_RDONLY, 0); if (Indbm == NULL) { printf("Unable to open input database %s\n", argv[1]); exit(1); } Scandbm = dbm_open(argv[1], O_RDONLY, 0); if (Scandbm == NULL) { printf("Unable to open input database %s\n", argv[1]); exit(1); } if (argv[2] == NULL) NoOutput = 1; else { Outdbm = dbm_open(argv[2], O_RDWR|O_CREAT|O_TRUNC, 0644); if (Outdbm == NULL) { printf("Unable to open output database %s\n", argv[2]); exit(1); } } ProcessMap(); dbm_close(Indbm); dbm_close(Scandbm); if (!NoOutput) { AddYPEntries(); dbm_close(Outdbm); } return (0); }