home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Usenet 1994 October
/
usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso
/
unix
/
volume25
/
hostcvt
/
main.c
< prev
next >
Wrap
C/C++ Source or Header
|
1992-01-03
|
10KB
|
464 lines
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <sys/stat.h>
#include <sys/file.h>
#ifndef lint
static char *RCSid = "$Id: main.c,v 1.4 91/11/25 17:46:06 rogers Release $";
#endif
struct netlist {
char *nl_net; /* Net number portion */
int nl_netlen; /* Length of above */
char *nl_file; /* File name */
FILE *nl_fp; /* Pointer to above */
struct netlist *nl_next; /* Next one */
};
typedef struct netlist nl_t;
typedef struct netlist *nl_tp;
struct host_names {
char *h_name;
char **h_aliases;
struct host_names *h_next;
};
typedef struct host_names hn_t;
typedef struct host_names *hn_tp;
char *soa = NULL; /* The soa from argv[] */
char *domain = NULL; /* Domain name from argv[] */
nl_tp ntop = NULL; /* Top of linked list */
hn_tp hntop = NULL; /* Top of list of hostnames */
char *hostsfile, *netfile, *soafile, *outputfile;
extern char *optarg; /* for egetopt() */
extern int optind; /* for egetopt() */
extern int errno;
extern char *sys_errlist[];
#define ERR sys_errlist[errno], errno
void exit();
main(argc, argv)
int argc;
char *argv[];
{
FILE *fopen();
char *strsave(), *malloc();
struct hostent *mygethostent();
register struct hostent *hp;
register FILE *fp;
register char *ipaddr, **cpp;
register nl_tp np;
struct in_addr foo;
char ch;
int hostflag, soaflag, netflag, errflag, outputflag, domainflag;
hostflag = soaflag = netflag = errflag = outputflag = domainflag = 0;
hostsfile = soafile = netfile = domain = outputfile = NULL;
while ((ch = egetopt(argc, argv, "h:n:o:s:")) != -1)
switch (ch) {
case 'h': /* assign name for "hosts" file (sourcefile) */
if (hostflag){
errflag++;
}
else {
hostsfile = strsave(optarg);
hostflag++;
}
break;
case 'n': /* assign name for "netlist" */
if (netflag){
errflag++;
}
else {
netfile = strsave(optarg);
netflag++;
}
break;
case 'o': /* assign name for main output file */
if (outputflag){
errflag++;
}
else {
outputfile = strsave(optarg);
outputflag++;
}
break;
case 's': /* assign name for "soabasefile" */
if (soaflag){
errflag++;
}
else {
soafile = strsave(optarg);
soaflag++;
}
break;
case '?': /* anything else that might show up */
errflag++;
} /* switch */
for (; optind < argc; optind++) {
if (domainflag) {
errflag++;
break;
} /* if */
else {
domain = strsave(argv[optind]);
domainflag++;
} /* else */
} /* for */
if (errflag || domain == NULL || (strlen(domain) < 2)) {
(void) fprintf(stderr, "usage: hostcvt [-h hostsfile] [-n netlistfile]\n\t\t[-s soabasefile] [-o outputfile] domain\n");
exit(2);
}
if (!netflag){
netfile = strsave("netlist");
}
if (!hostflag){
hostsfile = strsave("hosts.thisdomain");
}
if (!soafile) {
soafile = strsave("soabasefile");
}
if (!outputflag){
outputfile = domain;
}
rdsoa(soafile);
(void)close(0);
(void)close(1);
if((fp = fopen(outputfile, "w")) == NULL) {
(void) fprintf(stderr, "hostcvt: could not open %s\n", outputfile);
exit(1);
}
if(access(hostsfile, R_OK) == -1) {
(void) fprintf(stderr, "hostcvt: no host file %s\n", hostsfile);
exit(1);
}
if(soa != NULL) {
(void) fputs(soa, fp);
}
rdnetlist();
while ((hp = mygethostent(hostsfile)) != NULL) {
foo.s_addr = (u_long) * ((u_long *) hp->h_addr);
ipaddr = inet_ntoa(foo);
if (outnet(ipaddr, hp->h_name)) {
if (isdup(hp)){
continue;
}
if (strlen(hp->h_name) == 0) {
(void)fprintf(stderr, "No name found for %s -- ignoring...\n", ipaddr);
}
else {
savehp(hp);
(void) fprintf(fp, "%s\t\tIN\tA\t%s\n", hp->h_name, ipaddr);
for (cpp = hp->h_aliases; *cpp != NULL; cpp++) {
if (strcasecmp(*cpp, hp->h_name) != 0) {
(void) fprintf(fp, "%s\t\tIN\tCNAME\t%s\n", *cpp, hp->h_name);
}
} /* else */
}
}
}
(void) fflush(fp);
(void) fclose(fp);
for (np = ntop; np != NULL; np = np->nl_next) {
(void) fflush(np->nl_fp);
(void) fclose(np->nl_fp);
}
return(0);
}
/*
* See if the new hostname or any of it's aliases
* are already known.
*/
int
isdup(hp)
register struct hostent *hp;
{
register hn_tp np;
register char **cpp, **acp;
/*
* For each node in our linked list of known names....
*/
for (np = hntop; np != NULL; np = np->h_next) {
/*
* See if the new name matches directly
*/
if (strcasecmp(hp->h_name, np->h_name) == 0) {
(void) fprintf(stderr, "hostcvt: duplicated name: %s\n", hp->h_name);
return (1);
}
/*
* See if the new name matches an alias
*/
for (acp = np->h_aliases; *acp != NULL; acp++) {
if (strcasecmp(hp->h_name, *acp) == 0) {
(void) fprintf(stderr, "hostcvt: duplicated name to alias: %s\n", hp->h_name);
return (1);
}
}
/*
* For each of the new machines aliases
*/
for (cpp = hp->h_aliases; *cpp != NULL; cpp++) {
/*
* See if the alias matches the real name
*/
if (strcasecmp(*cpp, np->h_name) == 0) {
(void) fprintf(stderr, "hostcvt: duplicated alias to name: %s\n", hp->h_name);
return (1);
}
/*
* See if the alias matches one of our aliases
*/
for (acp = np->h_aliases; *acp != NULL; acp++) {
if (strcasecmp(*acp, *cpp) == 0) {
(void) fprintf(stderr, "hostcvt: duplicated alias to alias: %s\n", hp->h_name);
return (1);
}
}
}
}
return (0); /* No match */
}
savehp(hp)
register struct hostent *hp;
{
char *malloc(), *strsave();
register char **cpp, **acp;
register int cnt;
register hn_tp np;
if ((np = (hn_tp) malloc(sizeof(hn_t))) == NULL) {
(void) fprintf(stderr, "hostcvt: could not malloc in savehp()!\n");
exit(1);
}
np->h_name = strsave(hp->h_name);
for (cnt = 1, cpp = hp->h_aliases; *cpp != NULL; cpp++)
cnt++;
if ((np->h_aliases = (char **) malloc((unsigned) (cnt * sizeof(char **)))) == NULL) {
(void) fprintf(stderr, "hostcvt: could not malloc in savehp()!\n");
exit(1);
}
for (cpp = hp->h_aliases, acp = np->h_aliases; *cpp != NULL; cpp++, acp++) {
*acp = strsave(*cpp);
}
*acp = NULL;
np->h_next = hntop;
hntop = np;
}
/*
* Add the host named "name" at the IP address "ip" to
* the proper net file. Return 1 if done OK, 0 if not.
*/
int
outnet(ip, name)
char *ip, *name;
{
char *strcpy(), *index(), *strsave();
register nl_tp np;
register int i;
register char *last, *cp, *ipaddr;
char dig[4][20];
ipaddr = strsave(ip);
for (np = ntop; np != NULL; np = np->nl_next) {
if (strncmp(ipaddr, np->nl_net, np->nl_netlen) == 0) {
last = ipaddr + np->nl_netlen;
bzero((char *) dig, sizeof(dig));
for (i = 0; *last != '\0'; i++) {
if ((cp = index(last, '.')) == NULL){
break;
}
*cp = '\0';
(void) strcpy(dig[i], last);
last = cp + 1;
}
(void) fprintf(np->nl_fp, "%s", last);
for (i = 3; i >= 0; i--) {
if (dig[i][0] != '\0'){
(void) fprintf(np->nl_fp, ".%s", dig[i]);
}
}
(void) fprintf(np->nl_fp, "\t\tIN\tPTR\t%s.%s.\n", name, domain);
return (1);
}
}
(void) fprintf(stderr, "hostcvt: could not find file for %s (add= %s)\n", name, ipaddr);
return (0);
}
rdnetlist()
{
char *strsave(), *malloc(), *index();
FILE *fopen();
register FILE *fp;
register nl_tp np;
register int i, cnt;
char nbuf[256], fbuf[512], buf[BUFSIZ];
if ((fp = fopen(netfile, "r")) == NULL) {
(void) fprintf(stderr, "hostcvt: could not open %s\n", netfile);
exit(1);
}
for (i = 1, cnt = 0; fgets(buf, BUFSIZ, fp) != NULL; i++) {
if (buf[0] == '#' || buf[0] == '\n'){ /* allow comments and blanks */
continue;
}
if (sscanf(buf, "%s %s", nbuf, fbuf) != 2) {
(void) fprintf(stderr, "hostcvt: error on line #%d in %s, contents= %s", i, netfile, buf);
continue;
}
if ((np = (nl_tp) malloc(sizeof(nl_t))) == NULL) {
(void) fprintf(stderr, "hostcvt: could not malloc!\n");
exit(1);
}
np->nl_net = strsave(nbuf);
np->nl_netlen = strlen(nbuf);
np->nl_file = strsave(fbuf);
np->nl_fp = NULL;
np->nl_next = ntop;
ntop = np;
cnt++;
}
(void) fclose(fp);
/*
* figure out how many open files we can have: Max (getdtablesize) minus:
* 1 for stderr (stdin & stdout closed) 1 for domain (output) file
* (argv[1])
*/
i = getdtablesize() - 2;
if (cnt > i) {
(void) fprintf(stderr, "hostcvt: can not have more than %d entries (you have %d)\n", i, cnt);
exit(1);
}
for (np = ntop; np != NULL; np = np->nl_next) {
if ((np->nl_fp = fopen(np->nl_file, "w")) == NULL) {
(void) fprintf(stderr, "hostcvt: could not open %s for write\n", np->nl_file);
continue;
}
if (soa != NULL) {
(void) fputs(soa, np->nl_fp);
}
}
}
rdsoa(file)
char *file;
{
int read(), open(), fstat();
register int fd, rv;
struct stat stb;
if ((fd = open(file, O_RDONLY, 0)) == -1) {
soa = NULL;
(void) fprintf(stderr, "hostcvt: could not open SOA file, skipping\n");
return;
}
if (fstat(fd, &stb) == -1) {
(void) fprintf(stderr, "hostcvt: could not fstat %s (%d)\n", ERR);
exit(1);
}
if ((soa = malloc((unsigned) stb.st_size)) == NULL) {
(void) fprintf(stderr, "hostcvt: could not malloc enough for SOA file (%s)\n", file);
exit(1);
}
if ((rv = read(fd, soa, (int) stb.st_size)) != stb.st_size) {
(void) fprintf(stderr, "hostcvt: asked to read %d, got %d", (int) stb.st_size, rv);
if (rv == -1){
(void) fprintf(stderr, " - %s (%d)", ERR);
}
(void) fprintf(stderr, "\n");
exit(1);
}
(void) close(fd);
}
char *
strsave(str)
register char *str;
{
char *malloc(), *strcpy();
register char *cp;
if (str == NULL)
return (NULL);
if ((cp = malloc((unsigned) (strlen(str) + 1))) != NULL)
(void) strcpy(cp, str);
return (cp);
}