📄 ptrconvert.c
字号:
/************************************************************************************************** $Id: ptrconvert.c,v 1.14 2005/04/20 17:22:25 bboy Exp $ Outputs zone data in various formats. Copyright (C) 2002-2005 Don Moore <bboy@bboy.net> This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at Your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA**************************************************************************************************/#include "util.h"#include "libptr.h"char hostname[256]; /* Hostname of local machine */char ns[256], mbox[256]; /* Default NS/MBOX *//* Information about an imported zone */typedef struct _arpazone{ char name[30]; /* Zone name */ uint32_t id; /* Zone ID */ uint32_t low, high; /* Extent of IP addresses for zone */} ARPAZONE;ARPAZONE **Zones = NULL; /* List of zones to import */int numZones = 0; /* Number of zones in list */unsigned int zones_found = 0, zones_inserted = 0; /* Total new zones found and created */unsigned int rr_found = 0, rr_inserted = 0; /* Total resource records found/inserted *//************************************************************************************************** USAGE Display program usage information.**************************************************************************************************/static voidusage(int status){ if (status != EXIT_SUCCESS) { fprintf(stderr, _("Try `%s --help' for more information."), progname); fputs("\n", stderr); } else { printf(_("Usage: %s [OPTIONS]... NS MBOX"), progname); puts(""); puts(_("Convert pre-0.9.12 PTR table format to in-addr.arpa zones.")); puts("");/* puts("----------------------------------------------------------------------------78"); */ puts(_(" -D, --database=DB database name to use")); puts(_(" -h, --host=HOST connect to SQL server at HOST")); puts(_(" -p, --password=PASS password for SQL server (or prompt from tty)")); puts(_(" -u, --user=USER username for SQL server if not current user")); puts("");#if DEBUG_ENABLED puts(_(" -d, --debug enable debug output"));#endif puts(_(" -v, --verbose be more verbose while running (on by default)")); puts(_(" --help display this help and exit")); puts(_(" --version output version information and exit")); puts(""); printf(_("Report bugs to <%s>.\n"), PACKAGE_BUGREPORT); } exit(status);}/*--- usage() -----------------------------------------------------------------------------------*//************************************************************************************************** CMDLINE Process command line options.**************************************************************************************************/static voidcmdline(int argc, char **argv){ char *optstr; int optc, optindex; struct option const longopts[] = { {"database", required_argument, NULL, 'D'}, {"host", required_argument, NULL, 'h'}, {"password", optional_argument, NULL, 'p'}, {"user", required_argument, NULL, 'u'}, {"debug", no_argument, NULL, 'd'}, {"verbose", no_argument, NULL, 'v'}, {"help", no_argument, NULL, 0}, {"version", no_argument, NULL, 0}, {NULL, 0, NULL, 0} }; /* Set default NS and MBOX based on this machine's hostname */ gethostname(hostname, sizeof(hostname)-1); snprintf(ns, sizeof(ns), "%s.", hostname); snprintf(mbox, sizeof(mbox), "hostmaster.%s.", hostname); err_file = stdout; error_init(argv[0], LOG_USER); /* Init output routines */ optstr = getoptstr(longopts); while ((optc = getopt_long(argc, argv, optstr, longopts, &optindex)) != -1) { switch (optc) { case 0: { const char *opt = longopts[optindex].name; if (!strcmp(opt, "version")) /* --version */ { printf("%s ("PACKAGE_NAME") "PACKAGE_VERSION" ("SQL_VERSION_STR")\n", progname); puts("\n" PACKAGE_COPYRIGHT); puts(_("This is free software; see the source for copying conditions. There is NO")); puts(_("warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.")); exit(EXIT_SUCCESS); } else if (!strcmp(opt, "help")) /* --help */ usage(EXIT_SUCCESS); } break; case 'd': /* -d, --debug */#if DEBUG_ENABLED err_verbose = err_debug = 1;#endif break; case 'D': /* -D, --database=DB */ conf_set(&Conf, "database", optarg, 0); break; case 'h': /* -h, --host=HOST */ conf_set(&Conf, "db-host", optarg, 0); break; case 'p': /* -p, --password=PASS */ if (optarg) { conf_set(&Conf, "db-password", optarg, 0); memset(optarg, 'X', strlen(optarg)); } else conf_set(&Conf, "db-password", passinput(_("Enter password")), 0); break; case 'u': /* -u, --user=USER */ conf_set(&Conf, "db-user", optarg, 0); break; case 'v': /* -v, --verbose */ err_verbose = 1; break; default: usage(EXIT_FAILURE); } } /* Get NS and/or MBOX if specified */ if (optind < argc) snprintf(ns, sizeof(ns), "%s", (char *)argv[optind++]); if (optind < argc) snprintf(mbox, sizeof(mbox), "%s", (char *)argv[optind++]); if (LASTCHAR(ns) != '.') strncat(ns, ".", sizeof(ns) - strlen(ns) - 1); if (LASTCHAR(mbox) != '.') strncat(mbox, ".", sizeof(mbox) - strlen(mbox) - 1);}/*--- cmdline() ---------------------------------------------------------------------------------*//************************************************************************************************** LOAD_ZONE_LIST Examines all records in the 'ptr' table, constructing a list of zones to create.**************************************************************************************************/static voidload_zone_list(void){ SQL_RES *res; SQL_ROW row; char query[512]; size_t querylen; /* Construct and execute query */ querylen = snprintf(query, sizeof(query), "SELECT "MYDNS_PTR_FIELDS"%s FROM %s", (mydns_ptr_use_active ? ",active" : ""), mydns_ptr_table_name); if (!(res = sql_query(sql, query, querylen))) ErrSQL(sql, "Error selecting PTR records"); /* Add results to list */ while ((row = sql_getrow(res))) { uint32_t ip; uint8_t quad[4]; char addr[256], name[30]; register int n; MYDNS_PTR *ptr; if (mydns_ptr_use_active && row[4] && !GETBOOL(row[4])) continue; if (!(ptr = mydns_parse_ptr(row))) continue; /* Get IP address etc */ ip = htonl(ptr->ip); memcpy(&quad, &ip, sizeof(quad)); inet_ntop(AF_INET, &ip, addr, sizeof(addr)); /* Generate zone name */ snprintf(name, sizeof(name), "%u.%u.%u.in-addr.arpa.", quad[2], quad[1], quad[0]); /* Find zone */ for (n = 0; n < numZones; n++) if (!strcasecmp(Zones[n]->name, name)) break; /* Add new zone if not found */ if (n == numZones) { if (!Zones) { if (!(Zones = malloc((numZones + 1) * sizeof(ARPAZONE *)))) Err("malloc"); } else { if (!(Zones = realloc(Zones, (numZones + 1) * sizeof(ARPAZONE *)))) Err("realloc"); } if (!(Zones[numZones] = malloc(sizeof(ARPAZONE)))) Err("malloc"); strncpy(Zones[numZones]->name, name, sizeof(Zones[numZones]->name)-1); Zones[numZones]->id = 0; /* Get low/high extent of zone */ quad[3] = 0; memcpy(&ip, &quad, sizeof(ip)); Zones[numZones]->low = ntohl(ip); quad[3] = 255; memcpy(&ip, &quad, sizeof(ip)); Zones[numZones]->high = ntohl(ip); numZones++; } Free(ptr); } sql_free(res); if (!numZones) Errx("No zones found in PTR table."); Verbose("loaded %d distinct zone%s from \"%s\" table", numZones, S(numZones), mydns_ptr_table_name);}/*--- load_zone_list() --------------------------------------------------------------------------*//************************************************************************************************** GET_ZONE_IDS For each zone in the 'Zones' list, load the zone ID.**************************************************************************************************/voidget_zone_ids(void){ int n; for (n = 0; n < numZones; n++) { MYDNS_SOA *soa = NULL; /* Attempt to load pre-existing SOA */ if (!mydns_soa_load(sql, &soa, Zones[n]->name,0) && soa) //modi by zyl 080408 { Verbose("%s: Zone %u", Zones[n]->name, soa->id); Zones[n]->id = soa->id; mydns_soa_free(soa); zones_found++; } else /* Insert new record */ { long id; uchar query[DNS_QUERYBUFSIZ]; int querylen; char esc_origin[DNS_MAXNAMELEN + DNS_MAXNAMELEN + 1]; char esc_ns[520], esc_mbox[520]; sql_escstr(sql, esc_origin, Zones[n]->name, strlen(Zones[n]->name)); sql_escstr(sql, esc_ns, ns, strlen(ns)); sql_escstr(sql, esc_mbox, mbox, strlen(mbox)); /* Construct and issue query */ querylen = snprintf(query, sizeof(query), "INSERT INTO %s (origin,ns,mbox) VALUES ('%s','%s','%s')", mydns_soa_table_name, esc_origin, esc_ns, esc_mbox); if (sql_nrquery(sql, query, querylen) != 0) ErrSQL(sql, "%s: Error inserting zone", Zones[n]->name); if ((id = sql_count(sql, "SELECT id FROM soa WHERE origin='%s'", esc_origin)) < 0) ErrSQL(sql, "%s: Error getting zone ID", Zones[n]->name); Zones[n]->id = (uint32_t)id; Verbose("%s: Zone %u (new)", Zones[n]->name, Zones[n]->id); zones_inserted++; } }}/*--- get_zone_ids() ----------------------------------------------------------------------------*//************************************************************************************************** PTRCONVERT For each zone in 'Zones' list, gets all relevant records from the PTR table and inserts them into the appropriate zones.**************************************************************************************************/voidptrconvert(void){ int n; for (n = 0; n < numZones; n++) { SQL_RES *res; SQL_ROW row; char query[512]; char esc_origin[DNS_MAXNAMELEN + DNS_MAXNAMELEN + 1]; size_t querylen; int inserted = 0, found = 0; sql_escstr(sql, esc_origin, Zones[n]->name, strlen(Zones[n]->name)); querylen = snprintf(query, sizeof(query), "SELECT "MYDNS_PTR_FIELDS"%s FROM %s WHERE ip >= %u AND ip <= %u", (mydns_ptr_use_active ? ",active" : ""), mydns_ptr_table_name, Zones[n]->low, Zones[n]->high); if (!(res = sql_query(sql, query, querylen))) ErrSQL(sql, "Error selecting PTR records"); /* Insert RR for each result */ while ((row = sql_getrow(res))) { MYDNS_PTR *ptr; uint32_t ip; uint8_t quad[4]; long rv; if (mydns_ptr_use_active && row[4] && !GETBOOL(row[4])) continue; /* Get PTR data and quad values */ if (!(ptr = mydns_parse_ptr(row))) continue; ip = htonl(ptr->ip); memcpy(&quad, &ip, sizeof(quad)); /* See if this record already exists */ rv = sql_count(sql, "SELECT COUNT(*) FROM %s" " WHERE zone=%u AND type='PTR' AND (name='%u' OR name='%u.%s')", mydns_rr_table_name, Zones[n]->id, quad[3], quad[3], Zones[n]->name); if (rv == 0) { char esc_data[DNS_MAXNAMELEN + DNS_MAXNAMELEN + 1]; sql_escstr(sql, esc_data, ptr->name, strlen(ptr->name)); querylen = snprintf(query, sizeof(query), "INSERT INTO %s (zone,name,type,data,ttl) VALUES (%u,'%u','PTR','%s',%u)", mydns_rr_table_name, Zones[n]->id, quad[3], esc_data, ptr->ttl); if (sql_nrquery(sql, query, querylen) != 0) ErrSQL(sql, "%s: Error inserting rr", Zones[n]->name); inserted++; rr_inserted++; } else if (rv > 0) { found++; rr_found++; } else if (rv < 0) ErrSQL(sql, "Error looking for existing resource record"); Free(ptr); } Verbose("%s: %d record%s (%d found, %d inserted)", Zones[n]->name, found + inserted, S(found + inserted), found, inserted); sql_free(res); }}/*--- ptrconvert() ------------------------------------------------------------------------------*//************************************************************************************************** MAIN**************************************************************************************************/intmain(int argc, char **argv){ setlocale(LC_ALL, ""); /* Internationalization */ bindtextdomain(PACKAGE, LOCALEDIR); textdomain(PACKAGE); cmdline(argc, argv); load_config(); mydns_set_ptr_table_name(conf_get(&Conf, "ptr-table", NULL)); db_connect(); if (!sql_istable(sql, mydns_ptr_table_name)) { Notice(_("No table `%s' in database"), mydns_ptr_table_name); Notice(_("Your setup is correct; you don't need to run this program")); exit(EXIT_FAILURE); } if (mydns_set_ptr_use_active(sql) > 0) Verbose(_("optional \"active\" column found in \"%s\" table"), mydns_ptr_table_name); Verbose("Default nameserver is \"%s\"", ns); Verbose("Default mailbox is \"%s\"", mbox); load_zone_list(); /* Get list of zones */ get_zone_ids(); /* Get zone ID for each zone */ ptrconvert(); /* Insert ptr records */ Notice("processed %d zone%s (%d found, %d created)", zones_found + zones_inserted, S(zones_found + zones_inserted), zones_found, zones_inserted); Notice("processed %d resource record%s (%d found, %d created)", rr_found + rr_inserted, S(rr_found + rr_inserted), rr_found, rr_inserted); return (0);}/*--- main() ------------------------------------------------------------------------------------*//* vi:set ts=3: *//* NEED_PO */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -