#include #include #include #include #include #include "dnsconf.h" #include "dnsconf.m" #include "netconf.h" #include "internal.h" PUBLIC RECORD::RECORD(RECORD_TYPE _id) { id = _id; } /* Tell if a record is of a certain type (A,SOA */ PUBLIC bool RECORD::is(RECORD_TYPE _id) { return id == _id; } PUBLIC VIRTUAL void RECORD::sethostpart(const char *) //hostpart { // This is really an assert. This means that sethostpart was // called on this type of record and it was not overridend // Most record don't need sethostpart so a virtual pure function // would have introduced more work fprintf (stderr,MSG_U(E_SETHOSTPART,"Can't set host part for record type %d\n"),id); } /* Primary key comparison between record of the same type This function is the default for record that are not compared. */ PROTECTED VIRTUAL int RECORD::cmpsame(const RECORD *) //other { assert (0); return -1; } /* Change the content of a record (The value, not the key) by copying another record. */ PUBLIC VIRTUAL int RECORD::set(const RECORD *) //other { assert (0); return -1; } /* Compare two record. Return -1 if they are not of the same type. Return a strcmp() of their primary key if they are of the same type, */ PUBLIC int RECORD::cmp(RECORD *other) { int ret = -1; if (id == other->id){ ret = cmpsame(other); } return ret; } /* Compare the left value of a record with a string. Return the output of strcmp(). */ PUBLIC VIRTUAL int RECORD::cmp_left(const char *) { return -1; } /* Return the left part of a record. */ PUBLIC VIRTUAL const char *RECORD::get_left() { return NULL; } /* Compare the right value of a record with a string. Return the output of strcmp(). */ PUBLIC VIRTUAL int RECORD::cmp_right(const char *) { return -1; } PUBLIC RECORD_IN::RECORD_IN( const RECORD_PARSE &p, RECORD_TYPE _id) : RECORD (_id) { strcpy (ttlstr,p.ttl); } PUBLIC RECORD_IN::RECORD_IN(RECORD_TYPE _id) :RECORD (_id) { ttlstr[0] = '\0'; } PUBLIC const char *RECORD_IN::getttl() { return ttlstr; } /* Transform a TTL in seconds, into either days, hours or minutes if it fits */ void record_formatttl (long seconds, char dst[20]) { static int tbsec[]={ 24*60*60, // One day 60*60, // One hour 60 // One minute }; static char letters[]="DHM"; dst[0] = '\0'; for (int i=0; i<3; i++){ if (seconds % tbsec[i] == 0){ sprintf (dst,"%ld%c",seconds / tbsec[i],letters[i]); break; } } if (dst[0] == '\0') sprintf (dst,"%ld",seconds); } PUBLIC void RECORD_IN::setttl(const char *s) { ttlstr[0] = '\0'; if (s != NULL && s[0] != '\0'){ TIMESTR t(s); record_formatttl (t.seconds,ttlstr); } } PUBLIC void RECORD_IN::setttl(const SSTRING *s) { ttlstr[0] = '\0'; if (s != NULL){ setttl (s->get()); } } PUBLIC void RECORD::setcomment(const char *str) { comment.setfrom (str); } PUBLIC RECORD_COMMENT::RECORD_COMMENT (const char *str) : RECORD (RTYPE_COMMENT) { setcomment (str); } PUBLIC void RECORD_COMMENT::print (FILE_CFG *fout) const { fprintf (fout,"%s\n",comment.get()); } PUBLIC RECORD_IN_A::RECORD_IN_A(const RECORD_PARSE &p) : RECORD_IN(p,RTYPE_A) { name.setfrom (p.f1); addr.setfrom (p.f2); } PUBLIC RECORD_IN_A::RECORD_IN_A( const char *_name, const char *_addr) : RECORD_IN(RTYPE_A) { name.setfrom(_name); addr.setfrom(_addr); } PUBLIC void RECORD_IN_A::sethostpart (const char *hostpart) { name.setfrom (hostpart); } PROTECTED int RECORD_IN_A::cmpsame(const RECORD *other) { return name.icmp(((RECORD_IN_A*)other)->name); } PROTECTED int RECORD_IN_A::cmp_left(const char *str) { return name.icmp(str); } PROTECTED int RECORD_IN_A::cmp_right(const char *str) { return addr.cmp(str); } /* Return the left part of an A record. */ PUBLIC VIRTUAL const char *RECORD_IN_A::get_left() { return name.get(); } /* Change the content of a record (The value, not the key) by copying another record. */ PUBLIC int RECORD_IN_A::set(const RECORD *other) { addr.setfrom (((RECORD_IN_A*)other)->addr.get()); return 0; } /* Do a stricmp on the hostname */ PUBLIC int RECORD_IN_A::cmphost(const char *host) { return stricmp(host,name.get()); } PUBLIC void RECORD_IN_A::setip(const char *ip) { addr.setfrom(ip); } PUBLIC void RECORD_IN_A::print (FILE_CFG *fout) const { fprintf (fout,"%s\t%s\tIN\tA\t%s\n",name.get(),ttlstr,addr.get()); } PUBLIC RECORD_IN_PTR::RECORD_IN_PTR(const RECORD_PARSE &p) : RECORD_IN (p,RTYPE_PTR) { name.setfrom (p.f2); addr.setfrom (p.f1); } PUBLIC RECORD_IN_PTR::RECORD_IN_PTR( const char *iprev, const char *host) : RECORD_IN(RTYPE_PTR) { addr.setfrom(iprev); name.setfrom(host); dns_cnv2abs (name); } PROTECTED int RECORD_IN_PTR::cmpsame(const RECORD *other) { return name.icmp(((RECORD_IN_PTR*)other)->name); } PROTECTED int RECORD_IN_PTR::cmp_left(const char *str) { return addr.cmp(str); } PROTECTED int RECORD_IN_PTR::cmp_right(const char *str) { return name.cmp(str); } /* Change the content of a record (The value, not the key) by copying another record. */ PUBLIC int RECORD_IN_PTR::set(const RECORD *other) { name.setfrom (((RECORD_IN_PTR*)other)->name.get()); return 0; } PUBLIC void RECORD_IN_PTR::sethostpart (const char *hostpart) { addr.setfrom (hostpart); } PUBLIC void RECORD_IN_PTR::print (FILE_CFG *fout) const { fprintf (fout,"%s\t%s\tIN\tPTR\t%s\n",addr.get(),ttlstr,name.get()); } PUBLIC int RECORD_IN_PTR::cmpip(const char *ip) { return addr.cmp(ip); } PUBLIC RECORD_IN_NS::RECORD_IN_NS(const RECORD_PARSE &p) : RECORD_IN(p,RTYPE_NS) { name.setfrom (p.f1); ns.setfrom (p.f2); } PUBLIC RECORD_IN_NS::RECORD_IN_NS(const char *_name, const char *_ns) : RECORD_IN(RTYPE_NS) { name.setfrom (_name); ns.setfrom (_ns); dns_cnv2abs (ns); } /* Define the default NS record of a domain */ PUBLIC RECORD_IN_NS::RECORD_IN_NS() : RECORD_IN(RTYPE_NS) { THISHOST thost; name.setfrom ("@"); ns.setfrom(thost.getname1()); dns_cnv2abs (ns); } PROTECTED int RECORD_IN_NS::cmpsame(const RECORD *other) { return name.icmp(((RECORD_IN_NS*)other)->name); } /* Change the content of a record (The value, not the key) by copying another record. */ PUBLIC int RECORD_IN_NS::set(const RECORD *other) { ns.setfrom (((RECORD_IN_NS*)other)->ns.get()); return 0; } PUBLIC void RECORD_IN_NS::sethostpart (const char *hostpart) { name.setfrom (hostpart); } PUBLIC int RECORD_IN_NS::cmp_left (const char *str) { return name.icmp(str); } PUBLIC void RECORD_IN_NS::print (FILE_CFG *fout) const { fprintf (fout,"%s\t%s\tIN\tNS\t%s\n",name.get(),ttlstr,ns.get()); } PUBLIC RECORD_IN_CNAME::RECORD_IN_CNAME(const RECORD_PARSE &p) : RECORD_IN(p,RTYPE_CNAME) { nickname.setfrom (p.f1); name.setfrom (p.f2); dns_cnv2abs (name); } PUBLIC RECORD_IN_CNAME::RECORD_IN_CNAME(const char *cname, const char *realname) : RECORD_IN(RTYPE_CNAME) { nickname.setfrom (cname); name.setfrom (realname); dns_cnv2abs (name); } PUBLIC const char *RECORD_IN_CNAME::get_left() { return nickname.get(); } PUBLIC int RECORD_IN_CNAME::cmp_left (const char *str) { return nickname.cmp(str); } PUBLIC void RECORD_IN_CNAME::sethostpart (const char *hostpart) { nickname.setfrom (hostpart); } PROTECTED int RECORD_IN_CNAME::cmpsame(const RECORD *other) { return nickname.cmp(((RECORD_IN_CNAME*)other)->nickname); } PUBLIC void RECORD_IN_CNAME::print (FILE_CFG *fout) const { fprintf (fout,"%s\t%s\tIN\tCNAME\t%s\n",nickname.get(),ttlstr ,name.get()); } PUBLIC RECORD_IN_MX::RECORD_IN_MX(const RECORD_PARSE &p) : RECORD_IN(p,RTYPE_MX) { mailname.setfrom (p.f1); prefer = atoi(p.f2); servname.setfrom (p.f3); dns_cnv2abs (servname); } PUBLIC RECORD_IN_MX::RECORD_IN_MX( const char *_mailname, int priority, const char *_servname) : RECORD_IN(RTYPE_MX) { mailname.setfrom (_mailname); prefer = priority; servname.setfrom (_servname); dns_cnv2abs (servname); } PROTECTED int RECORD_IN_MX::cmpsame(const RECORD *other) { return mailname.cmp(((RECORD_IN_MX*)other)->mailname); } /* Change the content of a record (The value, not the key) by copying another record. */ PUBLIC int RECORD_IN_MX::set(const RECORD *other) { RECORD_IN_MX *othermx = (RECORD_IN_MX*)other; servname.setfrom(othermx->servname.get()); dns_cnv2abs (servname); prefer = othermx->prefer; return 0; } PUBLIC int RECORD_IN_MX::cmp_left (const char *str) { return mailname.cmp(str); } PUBLIC void RECORD_IN_MX::print (FILE_CFG *fout) const { fprintf (fout,"%s\t%s\tIN\tMX\t%d\t%s\n",mailname.get(),ttlstr ,prefer,servname.get()); } PUBLIC void RECORD_IN_MX::sethostpart (const char *hostpart) { mailname.setfrom (hostpart); } PUBLIC RECORD_IN_HINFO::RECORD_IN_HINFO( const char *_name, const char *_info) : RECORD_IN(RTYPE_HINFO) { name.setfrom (_name); info.setfrom (_info); } PROTECTED int RECORD_IN_HINFO::cmpsame(const RECORD *other) { return name.cmp(((RECORD_IN_HINFO*)other)->name); } PUBLIC void RECORD_IN_HINFO::print (FILE_CFG *fout) const { fprintf (fout,"%s\t%s\tIN\tHINFO\t%s\n",name.get(),ttlstr ,info.get()); } PUBLIC RECORD_IN_RP::RECORD_IN_RP( const char *_name, const char *_rp) : RECORD_IN(RTYPE_RP) { name.setfrom (_name); rp.setfrom (_rp); } PROTECTED int RECORD_IN_RP::cmpsame(const RECORD *other) { return name.cmp(((RECORD_IN_RP*)other)->name); } PUBLIC void RECORD_IN_RP::print (FILE_CFG *fout) const { fprintf (fout,"%s\t%s\tIN\tRP\t%s\n",name.get(),ttlstr ,rp.get()); } PUBLIC RECORD_IN_TXT::RECORD_IN_TXT( const char *_name, const char *_txt) : RECORD_IN(RTYPE_TXT) { name.setfrom (_name); txt.setfrom (_txt); } PROTECTED int RECORD_IN_TXT::cmpsame(const RECORD *other) { return name.cmp(((RECORD_IN_TXT*)other)->name); } PUBLIC void RECORD_IN_TXT::print (FILE_CFG *fout) const { fprintf (fout,"%s\t%s\tIN\tTXT\t%s\n",name.get(),ttlstr ,txt.get()); } PUBLIC RECORD_TTL::RECORD_TTL(const char *arg) : RECORD (RTYPE_TTL) { ttl.setfrom (arg); } PUBLIC RECORD_TTL::RECORD_TTL() : RECORD (RTYPE_TTL) { ttl.setfrom ("43200"); } PUBLIC void RECORD_TTL::print (FILE_CFG *fout) const { fprintf (fout,"$TTL\t%ld\n",ttl.seconds); } PUBLIC RECORD_PARSE::RECORD_PARSE() { ttl[0] = '\0'; f1[0] = f2[0] = f3[0] = f4[0] = f5[0] = f6[0] = f7[0] = f8[0] = '\0'; } PUBLIC RECORD_INCLUDE::RECORD_INCLUDE (const char *_path) : RECORD(RTYPE_INCLUDE) { path.setfrom (_path); } PUBLIC void RECORD_INCLUDE::print(FILE_CFG *fout) const { fprintf (fout,"$INCLUDE %s\n",path.get()); } PUBLIC RECORD_END_INCLUDE::RECORD_END_INCLUDE () : RECORD(RTYPE_END_INCLUDE) { } PUBLIC void RECORD_END_INCLUDE::print(FILE_CFG *) const { } PUBLIC RECORD *RECORDS::getitem(int no) const { return (RECORD*)ARRAY::getitem(no); } /* Save the record in a file */ PUBLIC int RECORDS::save (TBFILE &tbf) const { int ret = -1; for (int i=0; iis(RTYPE_INCLUDE)){ rec->print (tbf.cur); tbf.fopen (((RECORD_INCLUDE*)rec)->path.get(),"w"); }else if (rec->is(RTYPE_END_INCLUDE)){ tbf.fclose(); }else{ getitem(i)->print (tbf.cur); } } return ret; } #ifdef TEST int main (int argc, char *argv[]) { malloc_err (10); if (argc != 2){ fprintf (stderr,"File name\n"); }else{ RECORDS recs; recs.read (argv[1]); recs.save ("/tmp/toto"); } return 0; } #endif