diff options
author | stevel@tonic-gate <none@none> | 2005-06-14 00:00:00 -0700 |
---|---|---|
committer | stevel@tonic-gate <none@none> | 2005-06-14 00:00:00 -0700 |
commit | 7c478bd95313f5f23a4c958a745db2134aa03244 (patch) | |
tree | c871e58545497667cbb4b0a4f2daf204743e1fe7 /usr/src/cmd/ypcmd/mkalias.c | |
download | illumos-gate-7c478bd95313f5f23a4c958a745db2134aa03244.tar.gz |
OpenSolaris Launch
Diffstat (limited to 'usr/src/cmd/ypcmd/mkalias.c')
-rw-r--r-- | usr/src/cmd/ypcmd/mkalias.c | 358 |
1 files changed, 358 insertions, 0 deletions
diff --git a/usr/src/cmd/ypcmd/mkalias.c b/usr/src/cmd/ypcmd/mkalias.c new file mode 100644 index 0000000000..015132005d --- /dev/null +++ b/usr/src/cmd/ypcmd/mkalias.c @@ -0,0 +1,358 @@ +/* + * 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 (c) 1996, by Sun Microsystems, Inc. + * All rights reserved. + */ + +/* + * mkmap - program to convert the mail.aliases map into an + * inverse map of <user@host> back to <preferred-alias> + */ + +#pragma ident "%Z%%M% %I% %E% SMI" + +#include <stdlib.h> +#include <unistd.h> +#include <string.h> +#include <fcntl.h> +#include <ndbm.h> +#include <stdio.h> +#include <ctype.h> +#include <netdb.h> +#include <sys/systeminfo.h> + +#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) +{ + register 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] <input> <output>\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); +} |