4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License, Version 1.0 only
6 * (the "License"). You may not use this file except in compliance
9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 * or http://www.opensolaris.org/os/licensing.
11 * See the License for the specific language governing permissions
12 * and limitations under the License.
14 * When distributing Covered Code, include this CDDL HEADER in each
15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 * If applicable, add the following below this CDDL HEADER, with the
17 * fields enclosed by brackets "[]" replaced with your own identifying
18 * information: Portions Copyright [yyyy] [name of copyright owner]
23 * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
29 * mkmap - program to convert the mail.aliases map into an
30 * inverse map of <user@host> back to <preferred-alias>
33 #pragma ident "%Z%%M% %I% %E% SMI"
43 #include <sys/systeminfo.h>
50 #define MKAL_INCLUDE ":include:"
52 void CopyName(char *dst
, char *src
, int len
);
53 int HostCheck(char *h
, char *a
);
54 void DoName(char *cp
);
55 void UpperCase(char *cp
);
56 void AddYPEntries(void);
58 int Verbose
= 0; /* to get the gory details */
59 int UucpOK
= 0; /* pass all UUCP names right through */
60 int DomainOK
= 0; /* pass all Domain names (with dots) */
61 int ErrorCheck
= 0; /* check carefully for errors */
62 int NoOutput
= 0; /* no output, just do the check */
63 int Simple
= 0; /* Do not do the user name preference step */
64 int NameMode
= 0; /* Try to capitalize as names */
66 DBM
*Indbm
= NULL
, *Scandbm
= NULL
, *Outdbm
= NULL
;
69 IsMailingList(char *s
)
72 * returns true if the given string is a mailing list
81 if (p
&& strncmp(p
, MKAL_INCLUDE
, sizeof (MKAL_INCLUDE
)))
87 IsQualified(char *s
, char *p
, char *h
)
90 * returns true if the given string is qualified with a host name
92 register char *middle
;
94 middle
= strchr(s
, '@');
96 for (middle
= s
; *middle
!= '@'; *p
++ = *middle
++)
99 CopyName(h
, middle
+1, strlen(middle
+ 1));
102 middle
= strrchr(s
, '!');
106 CopyName(h
, s
, strlen(s
));
117 * returns true if the given string is one of the maintenence
118 * strings used in sendmail or NIS.
122 if (strncmp(s
, yp_prefix
, yp_prefix_sz
) == 0)
128 CopyName(char *dst
, char *src
, int len
)
131 * copy a string, but ignore white space
133 while (*src
&& len
--) {
143 Compare(char *s1
, char *s2
)
146 * compare strings, but ignore white space
148 while (*s1
!= '\0' && isspace(*s1
))
150 while (*s2
!= '\0' && isspace(*s2
))
152 return (strcmp(s1
, s2
));
158 datum key
, value
, part
, partvalue
;
159 char address
[PBLKSIZ
]; /* qualified version */
160 char user
[PBLKSIZ
]; /* unqualified version */
161 char userpart
[PBLKSIZ
]; /* unqualified part of qualified addr. */
162 char hostpart
[PBLKSIZ
]; /* rest of qualified addr. */
164 for (key
= dbm_firstkey(Scandbm
); key
.dptr
!= NULL
;
165 key
= dbm_nextkey(Scandbm
)) {
166 value
= dbm_fetch(Indbm
, key
);
167 CopyName(address
, value
.dptr
, value
.dsize
);
168 CopyName(user
, key
.dptr
, key
.dsize
);
169 if (address
== NULL
) continue;
170 if (IsMailingList(address
)) continue;
171 if (!IsQualified(address
, userpart
, hostpart
)) continue;
172 if (IsMaint(user
)) continue;
173 if (ErrorCheck
&& HostCheck(hostpart
, address
)) {
174 printf("Invalid host %s in %s:%s\n",
175 hostpart
, user
, address
);
178 part
.dptr
= userpart
;
179 part
.dsize
= strlen(userpart
) + 1;
181 partvalue
.dptr
= NULL
;
183 partvalue
= dbm_fetch(Indbm
, part
);
184 value
.dptr
= address
;
185 value
.dsize
= strlen(address
) + 1;
186 if (partvalue
.dptr
!= NULL
&&
187 Compare(partvalue
.dptr
, user
) == 0) {
192 dbm_store(Outdbm
, value
, part
, DBM_REPLACE
);
193 if (Verbose
) printf("%s --> %s --> %s\n",
194 userpart
, user
, address
);
199 key
.dsize
= strlen(user
) + 1;
201 dbm_store(Outdbm
, value
, key
, DBM_REPLACE
);
203 printf("%s --> %s\n", user
, address
);
210 * Returns true if this is an invalid host
213 HostCheck(char *h
, char *a
)
217 if (DomainOK
&& strchr(a
, '.'))
220 if (UucpOK
&& strchr(a
, '!'))
223 hp
= gethostbyname(h
);
228 * Apply some Heurisitcs to upper case-ify the name
229 * If it has a dot in it.
234 if (strchr(cp
, '.') == NULL
)
239 while (*cp
&& *cp
!= '-' && *cp
!= '.')
242 cp
++; /* skip past punctuation */
247 * upper cases one name - stops at a .
257 if (ch
== 'f' && cp
[1] == 'f')
258 return; /* handle ff */
260 if (ch
== 'm' && cp
[1] == 'c' && islower(cp
[2]))
261 cp
[2] = toupper(cp
[2]);
270 char last_modified
[PBLKSIZ
];
271 char host_name
[PBLKSIZ
];
275 * Add the special NIS entries.
277 key
.dptr
= yp_last_modified
;
278 key
.dsize
= yp_last_modified_sz
;
280 sprintf(last_modified
, "%10.10d", now
);
281 value
.dptr
= last_modified
;
282 value
.dsize
= strlen(value
.dptr
);
283 dbm_store(Outdbm
, key
, value
, DBM_REPLACE
);
285 key
.dptr
= yp_master_name
;
286 key
.dsize
= yp_master_name_sz
;
287 sysinfo(SI_HOSTNAME
, host_name
, sizeof (host_name
));
288 value
.dptr
= host_name
;
289 value
.dsize
= strlen(value
.dptr
);
290 dbm_store(Outdbm
, key
, value
, DBM_REPLACE
);
294 main(int argc
, char *argv
[])
296 while (argc
> 1 && argv
[1][0] == '-') {
297 switch (argv
[1][1]) {
323 printf("Unknown option %c\n", argv
[1][1]);
329 printf("Usage: mkalias [-e] [-v] [-u] [-d] [-s] [-n] <input> <output>\n");
332 Indbm
= dbm_open(argv
[1], O_RDONLY
, 0);
334 printf("Unable to open input database %s\n", argv
[1]);
337 Scandbm
= dbm_open(argv
[1], O_RDONLY
, 0);
338 if (Scandbm
== NULL
) {
339 printf("Unable to open input database %s\n", argv
[1]);
345 Outdbm
= dbm_open(argv
[2], O_RDWR
|O_CREAT
|O_TRUNC
, 0644);
346 if (Outdbm
== NULL
) {
347 printf("Unable to open output database %s\n", argv
[2]);