1*7b5038d7SDag-Erling Smørgrav /* 2*7b5038d7SDag-Erling Smørgrav * rdata.c 3*7b5038d7SDag-Erling Smørgrav * 4*7b5038d7SDag-Erling Smørgrav * rdata implementation 5*7b5038d7SDag-Erling Smørgrav * 6*7b5038d7SDag-Erling Smørgrav * a Net::DNS like library for C 7*7b5038d7SDag-Erling Smørgrav * 8*7b5038d7SDag-Erling Smørgrav * (c) NLnet Labs, 2004-2006 9*7b5038d7SDag-Erling Smørgrav * 10*7b5038d7SDag-Erling Smørgrav * See the file LICENSE for the license 11*7b5038d7SDag-Erling Smørgrav */ 12*7b5038d7SDag-Erling Smørgrav 13*7b5038d7SDag-Erling Smørgrav #include <ldns/config.h> 14*7b5038d7SDag-Erling Smørgrav 15*7b5038d7SDag-Erling Smørgrav #include <ldns/ldns.h> 16*7b5038d7SDag-Erling Smørgrav 17*7b5038d7SDag-Erling Smørgrav /* 18*7b5038d7SDag-Erling Smørgrav * Access functions 19*7b5038d7SDag-Erling Smørgrav * do this as functions to get type checking 20*7b5038d7SDag-Erling Smørgrav */ 21*7b5038d7SDag-Erling Smørgrav 22*7b5038d7SDag-Erling Smørgrav /* read */ 23*7b5038d7SDag-Erling Smørgrav size_t 24*7b5038d7SDag-Erling Smørgrav ldns_rdf_size(const ldns_rdf *rd) 25*7b5038d7SDag-Erling Smørgrav { 26*7b5038d7SDag-Erling Smørgrav assert(rd != NULL); 27*7b5038d7SDag-Erling Smørgrav return rd->_size; 28*7b5038d7SDag-Erling Smørgrav } 29*7b5038d7SDag-Erling Smørgrav 30*7b5038d7SDag-Erling Smørgrav ldns_rdf_type 31*7b5038d7SDag-Erling Smørgrav ldns_rdf_get_type(const ldns_rdf *rd) 32*7b5038d7SDag-Erling Smørgrav { 33*7b5038d7SDag-Erling Smørgrav assert(rd != NULL); 34*7b5038d7SDag-Erling Smørgrav return rd->_type; 35*7b5038d7SDag-Erling Smørgrav } 36*7b5038d7SDag-Erling Smørgrav 37*7b5038d7SDag-Erling Smørgrav uint8_t * 38*7b5038d7SDag-Erling Smørgrav ldns_rdf_data(const ldns_rdf *rd) 39*7b5038d7SDag-Erling Smørgrav { 40*7b5038d7SDag-Erling Smørgrav assert(rd != NULL); 41*7b5038d7SDag-Erling Smørgrav return rd->_data; 42*7b5038d7SDag-Erling Smørgrav } 43*7b5038d7SDag-Erling Smørgrav 44*7b5038d7SDag-Erling Smørgrav /* write */ 45*7b5038d7SDag-Erling Smørgrav void 46*7b5038d7SDag-Erling Smørgrav ldns_rdf_set_size(ldns_rdf *rd, size_t size) 47*7b5038d7SDag-Erling Smørgrav { 48*7b5038d7SDag-Erling Smørgrav assert(rd != NULL); 49*7b5038d7SDag-Erling Smørgrav rd->_size = size; 50*7b5038d7SDag-Erling Smørgrav } 51*7b5038d7SDag-Erling Smørgrav 52*7b5038d7SDag-Erling Smørgrav void 53*7b5038d7SDag-Erling Smørgrav ldns_rdf_set_type(ldns_rdf *rd, ldns_rdf_type type) 54*7b5038d7SDag-Erling Smørgrav { 55*7b5038d7SDag-Erling Smørgrav assert(rd != NULL); 56*7b5038d7SDag-Erling Smørgrav rd->_type = type; 57*7b5038d7SDag-Erling Smørgrav } 58*7b5038d7SDag-Erling Smørgrav 59*7b5038d7SDag-Erling Smørgrav void 60*7b5038d7SDag-Erling Smørgrav ldns_rdf_set_data(ldns_rdf *rd, void *data) 61*7b5038d7SDag-Erling Smørgrav { 62*7b5038d7SDag-Erling Smørgrav /* only copy the pointer */ 63*7b5038d7SDag-Erling Smørgrav assert(rd != NULL); 64*7b5038d7SDag-Erling Smørgrav rd->_data = data; 65*7b5038d7SDag-Erling Smørgrav } 66*7b5038d7SDag-Erling Smørgrav 67*7b5038d7SDag-Erling Smørgrav /* for types that allow it, return 68*7b5038d7SDag-Erling Smørgrav * the native/host order type */ 69*7b5038d7SDag-Erling Smørgrav uint8_t 70*7b5038d7SDag-Erling Smørgrav ldns_rdf2native_int8(const ldns_rdf *rd) 71*7b5038d7SDag-Erling Smørgrav { 72*7b5038d7SDag-Erling Smørgrav uint8_t data; 73*7b5038d7SDag-Erling Smørgrav 74*7b5038d7SDag-Erling Smørgrav /* only allow 8 bit rdfs */ 75*7b5038d7SDag-Erling Smørgrav if (ldns_rdf_size(rd) != LDNS_RDF_SIZE_BYTE) { 76*7b5038d7SDag-Erling Smørgrav return 0; 77*7b5038d7SDag-Erling Smørgrav } 78*7b5038d7SDag-Erling Smørgrav 79*7b5038d7SDag-Erling Smørgrav memcpy(&data, ldns_rdf_data(rd), sizeof(data)); 80*7b5038d7SDag-Erling Smørgrav return data; 81*7b5038d7SDag-Erling Smørgrav } 82*7b5038d7SDag-Erling Smørgrav 83*7b5038d7SDag-Erling Smørgrav uint16_t 84*7b5038d7SDag-Erling Smørgrav ldns_rdf2native_int16(const ldns_rdf *rd) 85*7b5038d7SDag-Erling Smørgrav { 86*7b5038d7SDag-Erling Smørgrav uint16_t data; 87*7b5038d7SDag-Erling Smørgrav 88*7b5038d7SDag-Erling Smørgrav /* only allow 16 bit rdfs */ 89*7b5038d7SDag-Erling Smørgrav if (ldns_rdf_size(rd) != LDNS_RDF_SIZE_WORD) { 90*7b5038d7SDag-Erling Smørgrav return 0; 91*7b5038d7SDag-Erling Smørgrav } 92*7b5038d7SDag-Erling Smørgrav 93*7b5038d7SDag-Erling Smørgrav memcpy(&data, ldns_rdf_data(rd), sizeof(data)); 94*7b5038d7SDag-Erling Smørgrav return ntohs(data); 95*7b5038d7SDag-Erling Smørgrav } 96*7b5038d7SDag-Erling Smørgrav 97*7b5038d7SDag-Erling Smørgrav uint32_t 98*7b5038d7SDag-Erling Smørgrav ldns_rdf2native_int32(const ldns_rdf *rd) 99*7b5038d7SDag-Erling Smørgrav { 100*7b5038d7SDag-Erling Smørgrav uint32_t data; 101*7b5038d7SDag-Erling Smørgrav 102*7b5038d7SDag-Erling Smørgrav /* only allow 32 bit rdfs */ 103*7b5038d7SDag-Erling Smørgrav if (ldns_rdf_size(rd) != LDNS_RDF_SIZE_DOUBLEWORD) { 104*7b5038d7SDag-Erling Smørgrav return 0; 105*7b5038d7SDag-Erling Smørgrav } 106*7b5038d7SDag-Erling Smørgrav 107*7b5038d7SDag-Erling Smørgrav memcpy(&data, ldns_rdf_data(rd), sizeof(data)); 108*7b5038d7SDag-Erling Smørgrav return ntohl(data); 109*7b5038d7SDag-Erling Smørgrav } 110*7b5038d7SDag-Erling Smørgrav 111*7b5038d7SDag-Erling Smørgrav time_t 112*7b5038d7SDag-Erling Smørgrav ldns_rdf2native_time_t(const ldns_rdf *rd) 113*7b5038d7SDag-Erling Smørgrav { 114*7b5038d7SDag-Erling Smørgrav uint32_t data; 115*7b5038d7SDag-Erling Smørgrav 116*7b5038d7SDag-Erling Smørgrav switch(ldns_rdf_get_type(rd)) { 117*7b5038d7SDag-Erling Smørgrav case LDNS_RDF_TYPE_TIME: 118*7b5038d7SDag-Erling Smørgrav memcpy(&data, ldns_rdf_data(rd), sizeof(data)); 119*7b5038d7SDag-Erling Smørgrav return (time_t)ntohl(data); 120*7b5038d7SDag-Erling Smørgrav default: 121*7b5038d7SDag-Erling Smørgrav return 0; 122*7b5038d7SDag-Erling Smørgrav } 123*7b5038d7SDag-Erling Smørgrav } 124*7b5038d7SDag-Erling Smørgrav 125*7b5038d7SDag-Erling Smørgrav ldns_rdf * 126*7b5038d7SDag-Erling Smørgrav ldns_native2rdf_int8(ldns_rdf_type type, uint8_t value) 127*7b5038d7SDag-Erling Smørgrav { 128*7b5038d7SDag-Erling Smørgrav return ldns_rdf_new_frm_data(type, LDNS_RDF_SIZE_BYTE, &value); 129*7b5038d7SDag-Erling Smørgrav } 130*7b5038d7SDag-Erling Smørgrav 131*7b5038d7SDag-Erling Smørgrav ldns_rdf * 132*7b5038d7SDag-Erling Smørgrav ldns_native2rdf_int16(ldns_rdf_type type, uint16_t value) 133*7b5038d7SDag-Erling Smørgrav { 134*7b5038d7SDag-Erling Smørgrav uint16_t *rdf_data = LDNS_XMALLOC(uint16_t, 1); 135*7b5038d7SDag-Erling Smørgrav ldns_rdf* rdf; 136*7b5038d7SDag-Erling Smørgrav if (!rdf_data) { 137*7b5038d7SDag-Erling Smørgrav return NULL; 138*7b5038d7SDag-Erling Smørgrav } 139*7b5038d7SDag-Erling Smørgrav ldns_write_uint16(rdf_data, value); 140*7b5038d7SDag-Erling Smørgrav rdf = ldns_rdf_new(type, LDNS_RDF_SIZE_WORD, rdf_data); 141*7b5038d7SDag-Erling Smørgrav if(!rdf) 142*7b5038d7SDag-Erling Smørgrav LDNS_FREE(rdf_data); 143*7b5038d7SDag-Erling Smørgrav return rdf; 144*7b5038d7SDag-Erling Smørgrav } 145*7b5038d7SDag-Erling Smørgrav 146*7b5038d7SDag-Erling Smørgrav ldns_rdf * 147*7b5038d7SDag-Erling Smørgrav ldns_native2rdf_int32(ldns_rdf_type type, uint32_t value) 148*7b5038d7SDag-Erling Smørgrav { 149*7b5038d7SDag-Erling Smørgrav uint32_t *rdf_data = LDNS_XMALLOC(uint32_t, 1); 150*7b5038d7SDag-Erling Smørgrav ldns_rdf* rdf; 151*7b5038d7SDag-Erling Smørgrav if (!rdf_data) { 152*7b5038d7SDag-Erling Smørgrav return NULL; 153*7b5038d7SDag-Erling Smørgrav } 154*7b5038d7SDag-Erling Smørgrav ldns_write_uint32(rdf_data, value); 155*7b5038d7SDag-Erling Smørgrav rdf = ldns_rdf_new(type, LDNS_RDF_SIZE_DOUBLEWORD, rdf_data); 156*7b5038d7SDag-Erling Smørgrav if(!rdf) 157*7b5038d7SDag-Erling Smørgrav LDNS_FREE(rdf_data); 158*7b5038d7SDag-Erling Smørgrav return rdf; 159*7b5038d7SDag-Erling Smørgrav } 160*7b5038d7SDag-Erling Smørgrav 161*7b5038d7SDag-Erling Smørgrav ldns_rdf * 162*7b5038d7SDag-Erling Smørgrav ldns_native2rdf_int16_data(size_t size, uint8_t *data) 163*7b5038d7SDag-Erling Smørgrav { 164*7b5038d7SDag-Erling Smørgrav uint8_t *rdf_data = LDNS_XMALLOC(uint8_t, size + 2); 165*7b5038d7SDag-Erling Smørgrav ldns_rdf* rdf; 166*7b5038d7SDag-Erling Smørgrav if (!rdf_data) { 167*7b5038d7SDag-Erling Smørgrav return NULL; 168*7b5038d7SDag-Erling Smørgrav } 169*7b5038d7SDag-Erling Smørgrav ldns_write_uint16(rdf_data, size); 170*7b5038d7SDag-Erling Smørgrav memcpy(rdf_data + 2, data, size); 171*7b5038d7SDag-Erling Smørgrav rdf = ldns_rdf_new(LDNS_RDF_TYPE_INT16_DATA, size + 2, rdf_data); 172*7b5038d7SDag-Erling Smørgrav if(!rdf) 173*7b5038d7SDag-Erling Smørgrav LDNS_FREE(rdf_data); 174*7b5038d7SDag-Erling Smørgrav return rdf; 175*7b5038d7SDag-Erling Smørgrav } 176*7b5038d7SDag-Erling Smørgrav 177*7b5038d7SDag-Erling Smørgrav /* note: data must be allocated memory */ 178*7b5038d7SDag-Erling Smørgrav ldns_rdf * 179*7b5038d7SDag-Erling Smørgrav ldns_rdf_new(ldns_rdf_type type, size_t size, void *data) 180*7b5038d7SDag-Erling Smørgrav { 181*7b5038d7SDag-Erling Smørgrav ldns_rdf *rd; 182*7b5038d7SDag-Erling Smørgrav rd = LDNS_MALLOC(ldns_rdf); 183*7b5038d7SDag-Erling Smørgrav if (!rd) { 184*7b5038d7SDag-Erling Smørgrav return NULL; 185*7b5038d7SDag-Erling Smørgrav } 186*7b5038d7SDag-Erling Smørgrav ldns_rdf_set_size(rd, size); 187*7b5038d7SDag-Erling Smørgrav ldns_rdf_set_type(rd, type); 188*7b5038d7SDag-Erling Smørgrav ldns_rdf_set_data(rd, data); 189*7b5038d7SDag-Erling Smørgrav return rd; 190*7b5038d7SDag-Erling Smørgrav } 191*7b5038d7SDag-Erling Smørgrav 192*7b5038d7SDag-Erling Smørgrav ldns_rdf * 193*7b5038d7SDag-Erling Smørgrav ldns_rdf_new_frm_data(ldns_rdf_type type, size_t size, const void *data) 194*7b5038d7SDag-Erling Smørgrav { 195*7b5038d7SDag-Erling Smørgrav ldns_rdf *rdf; 196*7b5038d7SDag-Erling Smørgrav 197*7b5038d7SDag-Erling Smørgrav /* if the size is too big, fail */ 198*7b5038d7SDag-Erling Smørgrav if (size > LDNS_MAX_RDFLEN) { 199*7b5038d7SDag-Erling Smørgrav return NULL; 200*7b5038d7SDag-Erling Smørgrav } 201*7b5038d7SDag-Erling Smørgrav 202*7b5038d7SDag-Erling Smørgrav /* allocate space */ 203*7b5038d7SDag-Erling Smørgrav rdf = LDNS_MALLOC(ldns_rdf); 204*7b5038d7SDag-Erling Smørgrav if (!rdf) { 205*7b5038d7SDag-Erling Smørgrav return NULL; 206*7b5038d7SDag-Erling Smørgrav } 207*7b5038d7SDag-Erling Smørgrav rdf->_data = LDNS_XMALLOC(uint8_t, size); 208*7b5038d7SDag-Erling Smørgrav if (!rdf->_data) { 209*7b5038d7SDag-Erling Smørgrav LDNS_FREE(rdf); 210*7b5038d7SDag-Erling Smørgrav return NULL; 211*7b5038d7SDag-Erling Smørgrav } 212*7b5038d7SDag-Erling Smørgrav 213*7b5038d7SDag-Erling Smørgrav /* set the values */ 214*7b5038d7SDag-Erling Smørgrav ldns_rdf_set_type(rdf, type); 215*7b5038d7SDag-Erling Smørgrav ldns_rdf_set_size(rdf, size); 216*7b5038d7SDag-Erling Smørgrav memcpy(rdf->_data, data, size); 217*7b5038d7SDag-Erling Smørgrav 218*7b5038d7SDag-Erling Smørgrav return rdf; 219*7b5038d7SDag-Erling Smørgrav } 220*7b5038d7SDag-Erling Smørgrav 221*7b5038d7SDag-Erling Smørgrav ldns_rdf * 222*7b5038d7SDag-Erling Smørgrav ldns_rdf_clone(const ldns_rdf *rd) 223*7b5038d7SDag-Erling Smørgrav { 224*7b5038d7SDag-Erling Smørgrav assert(rd != NULL); 225*7b5038d7SDag-Erling Smørgrav return (ldns_rdf_new_frm_data( ldns_rdf_get_type(rd), 226*7b5038d7SDag-Erling Smørgrav ldns_rdf_size(rd), ldns_rdf_data(rd))); 227*7b5038d7SDag-Erling Smørgrav } 228*7b5038d7SDag-Erling Smørgrav 229*7b5038d7SDag-Erling Smørgrav void 230*7b5038d7SDag-Erling Smørgrav ldns_rdf_deep_free(ldns_rdf *rd) 231*7b5038d7SDag-Erling Smørgrav { 232*7b5038d7SDag-Erling Smørgrav if (rd) { 233*7b5038d7SDag-Erling Smørgrav if (rd->_data) { 234*7b5038d7SDag-Erling Smørgrav LDNS_FREE(rd->_data); 235*7b5038d7SDag-Erling Smørgrav } 236*7b5038d7SDag-Erling Smørgrav LDNS_FREE(rd); 237*7b5038d7SDag-Erling Smørgrav } 238*7b5038d7SDag-Erling Smørgrav } 239*7b5038d7SDag-Erling Smørgrav 240*7b5038d7SDag-Erling Smørgrav void 241*7b5038d7SDag-Erling Smørgrav ldns_rdf_free(ldns_rdf *rd) 242*7b5038d7SDag-Erling Smørgrav { 243*7b5038d7SDag-Erling Smørgrav if (rd) { 244*7b5038d7SDag-Erling Smørgrav LDNS_FREE(rd); 245*7b5038d7SDag-Erling Smørgrav } 246*7b5038d7SDag-Erling Smørgrav } 247*7b5038d7SDag-Erling Smørgrav 248*7b5038d7SDag-Erling Smørgrav ldns_rdf * 249*7b5038d7SDag-Erling Smørgrav ldns_rdf_new_frm_str(ldns_rdf_type type, const char *str) 250*7b5038d7SDag-Erling Smørgrav { 251*7b5038d7SDag-Erling Smørgrav ldns_rdf *rdf = NULL; 252*7b5038d7SDag-Erling Smørgrav ldns_status status; 253*7b5038d7SDag-Erling Smørgrav 254*7b5038d7SDag-Erling Smørgrav switch (type) { 255*7b5038d7SDag-Erling Smørgrav case LDNS_RDF_TYPE_DNAME: 256*7b5038d7SDag-Erling Smørgrav status = ldns_str2rdf_dname(&rdf, str); 257*7b5038d7SDag-Erling Smørgrav break; 258*7b5038d7SDag-Erling Smørgrav case LDNS_RDF_TYPE_INT8: 259*7b5038d7SDag-Erling Smørgrav status = ldns_str2rdf_int8(&rdf, str); 260*7b5038d7SDag-Erling Smørgrav break; 261*7b5038d7SDag-Erling Smørgrav case LDNS_RDF_TYPE_INT16: 262*7b5038d7SDag-Erling Smørgrav status = ldns_str2rdf_int16(&rdf, str); 263*7b5038d7SDag-Erling Smørgrav break; 264*7b5038d7SDag-Erling Smørgrav case LDNS_RDF_TYPE_INT32: 265*7b5038d7SDag-Erling Smørgrav status = ldns_str2rdf_int32(&rdf, str); 266*7b5038d7SDag-Erling Smørgrav break; 267*7b5038d7SDag-Erling Smørgrav case LDNS_RDF_TYPE_A: 268*7b5038d7SDag-Erling Smørgrav status = ldns_str2rdf_a(&rdf, str); 269*7b5038d7SDag-Erling Smørgrav break; 270*7b5038d7SDag-Erling Smørgrav case LDNS_RDF_TYPE_AAAA: 271*7b5038d7SDag-Erling Smørgrav status = ldns_str2rdf_aaaa(&rdf, str); 272*7b5038d7SDag-Erling Smørgrav break; 273*7b5038d7SDag-Erling Smørgrav case LDNS_RDF_TYPE_STR: 274*7b5038d7SDag-Erling Smørgrav status = ldns_str2rdf_str(&rdf, str); 275*7b5038d7SDag-Erling Smørgrav break; 276*7b5038d7SDag-Erling Smørgrav case LDNS_RDF_TYPE_APL: 277*7b5038d7SDag-Erling Smørgrav status = ldns_str2rdf_apl(&rdf, str); 278*7b5038d7SDag-Erling Smørgrav break; 279*7b5038d7SDag-Erling Smørgrav case LDNS_RDF_TYPE_B64: 280*7b5038d7SDag-Erling Smørgrav status = ldns_str2rdf_b64(&rdf, str); 281*7b5038d7SDag-Erling Smørgrav break; 282*7b5038d7SDag-Erling Smørgrav case LDNS_RDF_TYPE_B32_EXT: 283*7b5038d7SDag-Erling Smørgrav status = ldns_str2rdf_b32_ext(&rdf, str); 284*7b5038d7SDag-Erling Smørgrav break; 285*7b5038d7SDag-Erling Smørgrav case LDNS_RDF_TYPE_HEX: 286*7b5038d7SDag-Erling Smørgrav status = ldns_str2rdf_hex(&rdf, str); 287*7b5038d7SDag-Erling Smørgrav break; 288*7b5038d7SDag-Erling Smørgrav case LDNS_RDF_TYPE_NSEC: 289*7b5038d7SDag-Erling Smørgrav status = ldns_str2rdf_nsec(&rdf, str); 290*7b5038d7SDag-Erling Smørgrav break; 291*7b5038d7SDag-Erling Smørgrav case LDNS_RDF_TYPE_TYPE: 292*7b5038d7SDag-Erling Smørgrav status = ldns_str2rdf_type(&rdf, str); 293*7b5038d7SDag-Erling Smørgrav break; 294*7b5038d7SDag-Erling Smørgrav case LDNS_RDF_TYPE_CLASS: 295*7b5038d7SDag-Erling Smørgrav status = ldns_str2rdf_class(&rdf, str); 296*7b5038d7SDag-Erling Smørgrav break; 297*7b5038d7SDag-Erling Smørgrav case LDNS_RDF_TYPE_CERT_ALG: 298*7b5038d7SDag-Erling Smørgrav status = ldns_str2rdf_cert_alg(&rdf, str); 299*7b5038d7SDag-Erling Smørgrav break; 300*7b5038d7SDag-Erling Smørgrav case LDNS_RDF_TYPE_ALG: 301*7b5038d7SDag-Erling Smørgrav status = ldns_str2rdf_alg(&rdf, str); 302*7b5038d7SDag-Erling Smørgrav break; 303*7b5038d7SDag-Erling Smørgrav case LDNS_RDF_TYPE_UNKNOWN: 304*7b5038d7SDag-Erling Smørgrav status = ldns_str2rdf_unknown(&rdf, str); 305*7b5038d7SDag-Erling Smørgrav break; 306*7b5038d7SDag-Erling Smørgrav case LDNS_RDF_TYPE_TIME: 307*7b5038d7SDag-Erling Smørgrav status = ldns_str2rdf_time(&rdf, str); 308*7b5038d7SDag-Erling Smørgrav break; 309*7b5038d7SDag-Erling Smørgrav case LDNS_RDF_TYPE_PERIOD: 310*7b5038d7SDag-Erling Smørgrav status = ldns_str2rdf_period(&rdf, str); 311*7b5038d7SDag-Erling Smørgrav break; 312*7b5038d7SDag-Erling Smørgrav case LDNS_RDF_TYPE_TSIG: 313*7b5038d7SDag-Erling Smørgrav status = ldns_str2rdf_tsig(&rdf, str); 314*7b5038d7SDag-Erling Smørgrav break; 315*7b5038d7SDag-Erling Smørgrav case LDNS_RDF_TYPE_SERVICE: 316*7b5038d7SDag-Erling Smørgrav status = ldns_str2rdf_service(&rdf, str); 317*7b5038d7SDag-Erling Smørgrav break; 318*7b5038d7SDag-Erling Smørgrav case LDNS_RDF_TYPE_LOC: 319*7b5038d7SDag-Erling Smørgrav status = ldns_str2rdf_loc(&rdf, str); 320*7b5038d7SDag-Erling Smørgrav break; 321*7b5038d7SDag-Erling Smørgrav case LDNS_RDF_TYPE_WKS: 322*7b5038d7SDag-Erling Smørgrav status = ldns_str2rdf_wks(&rdf, str); 323*7b5038d7SDag-Erling Smørgrav break; 324*7b5038d7SDag-Erling Smørgrav case LDNS_RDF_TYPE_NSAP: 325*7b5038d7SDag-Erling Smørgrav status = ldns_str2rdf_nsap(&rdf, str); 326*7b5038d7SDag-Erling Smørgrav break; 327*7b5038d7SDag-Erling Smørgrav case LDNS_RDF_TYPE_ATMA: 328*7b5038d7SDag-Erling Smørgrav status = ldns_str2rdf_atma(&rdf, str); 329*7b5038d7SDag-Erling Smørgrav break; 330*7b5038d7SDag-Erling Smørgrav case LDNS_RDF_TYPE_IPSECKEY: 331*7b5038d7SDag-Erling Smørgrav status = ldns_str2rdf_ipseckey(&rdf, str); 332*7b5038d7SDag-Erling Smørgrav break; 333*7b5038d7SDag-Erling Smørgrav case LDNS_RDF_TYPE_NSEC3_SALT: 334*7b5038d7SDag-Erling Smørgrav status = ldns_str2rdf_nsec3_salt(&rdf, str); 335*7b5038d7SDag-Erling Smørgrav break; 336*7b5038d7SDag-Erling Smørgrav case LDNS_RDF_TYPE_NSEC3_NEXT_OWNER: 337*7b5038d7SDag-Erling Smørgrav status = ldns_str2rdf_b32_ext(&rdf, str); 338*7b5038d7SDag-Erling Smørgrav break; 339*7b5038d7SDag-Erling Smørgrav case LDNS_RDF_TYPE_NONE: 340*7b5038d7SDag-Erling Smørgrav default: 341*7b5038d7SDag-Erling Smørgrav /* default default ??? */ 342*7b5038d7SDag-Erling Smørgrav status = LDNS_STATUS_ERR; 343*7b5038d7SDag-Erling Smørgrav break; 344*7b5038d7SDag-Erling Smørgrav } 345*7b5038d7SDag-Erling Smørgrav if (LDNS_STATUS_OK == status) { 346*7b5038d7SDag-Erling Smørgrav ldns_rdf_set_type(rdf, type); 347*7b5038d7SDag-Erling Smørgrav return rdf; 348*7b5038d7SDag-Erling Smørgrav } 349*7b5038d7SDag-Erling Smørgrav if (rdf) { 350*7b5038d7SDag-Erling Smørgrav LDNS_FREE(rdf); 351*7b5038d7SDag-Erling Smørgrav } 352*7b5038d7SDag-Erling Smørgrav return NULL; 353*7b5038d7SDag-Erling Smørgrav } 354*7b5038d7SDag-Erling Smørgrav 355*7b5038d7SDag-Erling Smørgrav ldns_status 356*7b5038d7SDag-Erling Smørgrav ldns_rdf_new_frm_fp(ldns_rdf **rdf, ldns_rdf_type type, FILE *fp) 357*7b5038d7SDag-Erling Smørgrav { 358*7b5038d7SDag-Erling Smørgrav return ldns_rdf_new_frm_fp_l(rdf, type, fp, NULL); 359*7b5038d7SDag-Erling Smørgrav } 360*7b5038d7SDag-Erling Smørgrav 361*7b5038d7SDag-Erling Smørgrav ldns_status 362*7b5038d7SDag-Erling Smørgrav ldns_rdf_new_frm_fp_l(ldns_rdf **rdf, ldns_rdf_type type, FILE *fp, int *line_nr) 363*7b5038d7SDag-Erling Smørgrav { 364*7b5038d7SDag-Erling Smørgrav char *line; 365*7b5038d7SDag-Erling Smørgrav ldns_rdf *r; 366*7b5038d7SDag-Erling Smørgrav ssize_t t; 367*7b5038d7SDag-Erling Smørgrav 368*7b5038d7SDag-Erling Smørgrav line = LDNS_XMALLOC(char, LDNS_MAX_LINELEN + 1); 369*7b5038d7SDag-Erling Smørgrav if (!line) { 370*7b5038d7SDag-Erling Smørgrav return LDNS_STATUS_MEM_ERR; 371*7b5038d7SDag-Erling Smørgrav } 372*7b5038d7SDag-Erling Smørgrav 373*7b5038d7SDag-Erling Smørgrav /* read an entire line in from the file */ 374*7b5038d7SDag-Erling Smørgrav if ((t = ldns_fget_token_l(fp, line, LDNS_PARSE_SKIP_SPACE, 0, line_nr)) == -1 || t == 0) { 375*7b5038d7SDag-Erling Smørgrav LDNS_FREE(line); 376*7b5038d7SDag-Erling Smørgrav return LDNS_STATUS_SYNTAX_RDATA_ERR; 377*7b5038d7SDag-Erling Smørgrav } 378*7b5038d7SDag-Erling Smørgrav r = ldns_rdf_new_frm_str(type, (const char*) line); 379*7b5038d7SDag-Erling Smørgrav LDNS_FREE(line); 380*7b5038d7SDag-Erling Smørgrav if (rdf) { 381*7b5038d7SDag-Erling Smørgrav *rdf = r; 382*7b5038d7SDag-Erling Smørgrav return LDNS_STATUS_OK; 383*7b5038d7SDag-Erling Smørgrav } else { 384*7b5038d7SDag-Erling Smørgrav return LDNS_STATUS_NULL; 385*7b5038d7SDag-Erling Smørgrav } 386*7b5038d7SDag-Erling Smørgrav } 387*7b5038d7SDag-Erling Smørgrav 388*7b5038d7SDag-Erling Smørgrav ldns_rdf * 389*7b5038d7SDag-Erling Smørgrav ldns_rdf_address_reverse(ldns_rdf *rd) 390*7b5038d7SDag-Erling Smørgrav { 391*7b5038d7SDag-Erling Smørgrav uint8_t buf_4[LDNS_IP4ADDRLEN]; 392*7b5038d7SDag-Erling Smørgrav uint8_t buf_6[LDNS_IP6ADDRLEN * 2]; 393*7b5038d7SDag-Erling Smørgrav ldns_rdf *rev; 394*7b5038d7SDag-Erling Smørgrav ldns_rdf *in_addr; 395*7b5038d7SDag-Erling Smørgrav ldns_rdf *ret_dname; 396*7b5038d7SDag-Erling Smørgrav uint8_t octet; 397*7b5038d7SDag-Erling Smørgrav uint8_t nnibble; 398*7b5038d7SDag-Erling Smørgrav uint8_t nibble; 399*7b5038d7SDag-Erling Smørgrav uint8_t i, j; 400*7b5038d7SDag-Erling Smørgrav 401*7b5038d7SDag-Erling Smørgrav char *char_dname; 402*7b5038d7SDag-Erling Smørgrav int nbit; 403*7b5038d7SDag-Erling Smørgrav 404*7b5038d7SDag-Erling Smørgrav if (ldns_rdf_get_type(rd) != LDNS_RDF_TYPE_A && 405*7b5038d7SDag-Erling Smørgrav ldns_rdf_get_type(rd) != LDNS_RDF_TYPE_AAAA) { 406*7b5038d7SDag-Erling Smørgrav return NULL; 407*7b5038d7SDag-Erling Smørgrav } 408*7b5038d7SDag-Erling Smørgrav 409*7b5038d7SDag-Erling Smørgrav in_addr = NULL; 410*7b5038d7SDag-Erling Smørgrav ret_dname = NULL; 411*7b5038d7SDag-Erling Smørgrav 412*7b5038d7SDag-Erling Smørgrav switch(ldns_rdf_get_type(rd)) { 413*7b5038d7SDag-Erling Smørgrav case LDNS_RDF_TYPE_A: 414*7b5038d7SDag-Erling Smørgrav /* the length of the buffer is 4 */ 415*7b5038d7SDag-Erling Smørgrav buf_4[3] = ldns_rdf_data(rd)[0]; 416*7b5038d7SDag-Erling Smørgrav buf_4[2] = ldns_rdf_data(rd)[1]; 417*7b5038d7SDag-Erling Smørgrav buf_4[1] = ldns_rdf_data(rd)[2]; 418*7b5038d7SDag-Erling Smørgrav buf_4[0] = ldns_rdf_data(rd)[3]; 419*7b5038d7SDag-Erling Smørgrav in_addr = ldns_dname_new_frm_str("in-addr.arpa."); 420*7b5038d7SDag-Erling Smørgrav if (!in_addr) { 421*7b5038d7SDag-Erling Smørgrav return NULL; 422*7b5038d7SDag-Erling Smørgrav } 423*7b5038d7SDag-Erling Smørgrav /* make a new rdf and convert that back */ 424*7b5038d7SDag-Erling Smørgrav rev = ldns_rdf_new_frm_data( LDNS_RDF_TYPE_A, 425*7b5038d7SDag-Erling Smørgrav LDNS_IP4ADDRLEN, (void*)&buf_4); 426*7b5038d7SDag-Erling Smørgrav if (!rev) { 427*7b5038d7SDag-Erling Smørgrav LDNS_FREE(in_addr); 428*7b5038d7SDag-Erling Smørgrav return NULL; 429*7b5038d7SDag-Erling Smørgrav } 430*7b5038d7SDag-Erling Smørgrav 431*7b5038d7SDag-Erling Smørgrav /* convert rev to a string */ 432*7b5038d7SDag-Erling Smørgrav char_dname = ldns_rdf2str(rev); 433*7b5038d7SDag-Erling Smørgrav if (!char_dname) { 434*7b5038d7SDag-Erling Smørgrav LDNS_FREE(in_addr); 435*7b5038d7SDag-Erling Smørgrav ldns_rdf_deep_free(rev); 436*7b5038d7SDag-Erling Smørgrav return NULL; 437*7b5038d7SDag-Erling Smørgrav } 438*7b5038d7SDag-Erling Smørgrav /* transform back to rdf with type dname */ 439*7b5038d7SDag-Erling Smørgrav ret_dname = ldns_dname_new_frm_str(char_dname); 440*7b5038d7SDag-Erling Smørgrav if (!ret_dname) { 441*7b5038d7SDag-Erling Smørgrav LDNS_FREE(in_addr); 442*7b5038d7SDag-Erling Smørgrav ldns_rdf_deep_free(rev); 443*7b5038d7SDag-Erling Smørgrav LDNS_FREE(char_dname); 444*7b5038d7SDag-Erling Smørgrav return NULL; 445*7b5038d7SDag-Erling Smørgrav } 446*7b5038d7SDag-Erling Smørgrav /* not needed anymore */ 447*7b5038d7SDag-Erling Smørgrav ldns_rdf_deep_free(rev); 448*7b5038d7SDag-Erling Smørgrav LDNS_FREE(char_dname); 449*7b5038d7SDag-Erling Smørgrav break; 450*7b5038d7SDag-Erling Smørgrav case LDNS_RDF_TYPE_AAAA: 451*7b5038d7SDag-Erling Smørgrav /* some foo magic to reverse the nibbles ... */ 452*7b5038d7SDag-Erling Smørgrav 453*7b5038d7SDag-Erling Smørgrav for (nbit = 127; nbit >= 0; nbit = nbit - 4) { 454*7b5038d7SDag-Erling Smørgrav /* calculate octett (8 bit) */ 455*7b5038d7SDag-Erling Smørgrav octet = ( ((unsigned int) nbit) & 0x78) >> 3; 456*7b5038d7SDag-Erling Smørgrav /* calculate nibble */ 457*7b5038d7SDag-Erling Smørgrav nnibble = ( ((unsigned int) nbit) & 0x04) >> 2; 458*7b5038d7SDag-Erling Smørgrav /* extract nibble */ 459*7b5038d7SDag-Erling Smørgrav nibble = (ldns_rdf_data(rd)[octet] & ( 0xf << (4 * (1 - 460*7b5038d7SDag-Erling Smørgrav nnibble)) ) ) >> ( 4 * (1 - 461*7b5038d7SDag-Erling Smørgrav nnibble)); 462*7b5038d7SDag-Erling Smørgrav 463*7b5038d7SDag-Erling Smørgrav buf_6[(LDNS_IP6ADDRLEN * 2 - 1) - 464*7b5038d7SDag-Erling Smørgrav (octet * 2 + nnibble)] = 465*7b5038d7SDag-Erling Smørgrav (uint8_t)ldns_int_to_hexdigit((int)nibble); 466*7b5038d7SDag-Erling Smørgrav } 467*7b5038d7SDag-Erling Smørgrav 468*7b5038d7SDag-Erling Smørgrav char_dname = LDNS_XMALLOC(char, (LDNS_IP6ADDRLEN * 4)); 469*7b5038d7SDag-Erling Smørgrav if (!char_dname) { 470*7b5038d7SDag-Erling Smørgrav return NULL; 471*7b5038d7SDag-Erling Smørgrav } 472*7b5038d7SDag-Erling Smørgrav char_dname[LDNS_IP6ADDRLEN * 4 - 1] = '\0'; /* closure */ 473*7b5038d7SDag-Erling Smørgrav 474*7b5038d7SDag-Erling Smørgrav /* walk the string and add . 's */ 475*7b5038d7SDag-Erling Smørgrav for (i = 0, j = 0; i < LDNS_IP6ADDRLEN * 2; i++, j = j + 2) { 476*7b5038d7SDag-Erling Smørgrav char_dname[j] = (char)buf_6[i]; 477*7b5038d7SDag-Erling Smørgrav if (i != LDNS_IP6ADDRLEN * 2 - 1) { 478*7b5038d7SDag-Erling Smørgrav char_dname[j + 1] = '.'; 479*7b5038d7SDag-Erling Smørgrav } 480*7b5038d7SDag-Erling Smørgrav } 481*7b5038d7SDag-Erling Smørgrav in_addr = ldns_dname_new_frm_str("ip6.arpa."); 482*7b5038d7SDag-Erling Smørgrav if (!in_addr) { 483*7b5038d7SDag-Erling Smørgrav LDNS_FREE(char_dname); 484*7b5038d7SDag-Erling Smørgrav return NULL; 485*7b5038d7SDag-Erling Smørgrav } 486*7b5038d7SDag-Erling Smørgrav 487*7b5038d7SDag-Erling Smørgrav /* convert rev to a string */ 488*7b5038d7SDag-Erling Smørgrav ret_dname = ldns_dname_new_frm_str(char_dname); 489*7b5038d7SDag-Erling Smørgrav LDNS_FREE(char_dname); 490*7b5038d7SDag-Erling Smørgrav if (!ret_dname) { 491*7b5038d7SDag-Erling Smørgrav ldns_rdf_deep_free(in_addr); 492*7b5038d7SDag-Erling Smørgrav return NULL; 493*7b5038d7SDag-Erling Smørgrav } 494*7b5038d7SDag-Erling Smørgrav break; 495*7b5038d7SDag-Erling Smørgrav default: 496*7b5038d7SDag-Erling Smørgrav break; 497*7b5038d7SDag-Erling Smørgrav } 498*7b5038d7SDag-Erling Smørgrav /* add the suffix */ 499*7b5038d7SDag-Erling Smørgrav rev = ldns_dname_cat_clone(ret_dname, in_addr); 500*7b5038d7SDag-Erling Smørgrav 501*7b5038d7SDag-Erling Smørgrav ldns_rdf_deep_free(ret_dname); 502*7b5038d7SDag-Erling Smørgrav ldns_rdf_deep_free(in_addr); 503*7b5038d7SDag-Erling Smørgrav return rev; 504*7b5038d7SDag-Erling Smørgrav } 505*7b5038d7SDag-Erling Smørgrav 506*7b5038d7SDag-Erling Smørgrav ldns_status 507*7b5038d7SDag-Erling Smørgrav ldns_octet(char *word, size_t *length) 508*7b5038d7SDag-Erling Smørgrav { 509*7b5038d7SDag-Erling Smørgrav char *s; 510*7b5038d7SDag-Erling Smørgrav char *p; 511*7b5038d7SDag-Erling Smørgrav *length = 0; 512*7b5038d7SDag-Erling Smørgrav 513*7b5038d7SDag-Erling Smørgrav for (s = p = word; *s != '\0'; s++,p++) { 514*7b5038d7SDag-Erling Smørgrav switch (*s) { 515*7b5038d7SDag-Erling Smørgrav case '.': 516*7b5038d7SDag-Erling Smørgrav if (s[1] == '.') { 517*7b5038d7SDag-Erling Smørgrav return LDNS_STATUS_EMPTY_LABEL; 518*7b5038d7SDag-Erling Smørgrav } 519*7b5038d7SDag-Erling Smørgrav *p = *s; 520*7b5038d7SDag-Erling Smørgrav (*length)++; 521*7b5038d7SDag-Erling Smørgrav break; 522*7b5038d7SDag-Erling Smørgrav case '\\': 523*7b5038d7SDag-Erling Smørgrav if ('0' <= s[1] && s[1] <= '9' && 524*7b5038d7SDag-Erling Smørgrav '0' <= s[2] && s[2] <= '9' && 525*7b5038d7SDag-Erling Smørgrav '0' <= s[3] && s[3] <= '9') { 526*7b5038d7SDag-Erling Smørgrav /* \DDD seen */ 527*7b5038d7SDag-Erling Smørgrav int val = ((s[1] - '0') * 100 + 528*7b5038d7SDag-Erling Smørgrav (s[2] - '0') * 10 + (s[3] - '0')); 529*7b5038d7SDag-Erling Smørgrav 530*7b5038d7SDag-Erling Smørgrav if (0 <= val && val <= 255) { 531*7b5038d7SDag-Erling Smørgrav /* this also handles \0 */ 532*7b5038d7SDag-Erling Smørgrav s += 3; 533*7b5038d7SDag-Erling Smørgrav *p = val; 534*7b5038d7SDag-Erling Smørgrav (*length)++; 535*7b5038d7SDag-Erling Smørgrav } else { 536*7b5038d7SDag-Erling Smørgrav return LDNS_STATUS_DDD_OVERFLOW; 537*7b5038d7SDag-Erling Smørgrav } 538*7b5038d7SDag-Erling Smørgrav } else { 539*7b5038d7SDag-Erling Smørgrav /* an espaced character, like \<space> ? 540*7b5038d7SDag-Erling Smørgrav * remove the '\' keep the rest */ 541*7b5038d7SDag-Erling Smørgrav *p = *++s; 542*7b5038d7SDag-Erling Smørgrav (*length)++; 543*7b5038d7SDag-Erling Smørgrav } 544*7b5038d7SDag-Erling Smørgrav break; 545*7b5038d7SDag-Erling Smørgrav case '\"': 546*7b5038d7SDag-Erling Smørgrav /* non quoted " Is either first or the last character in 547*7b5038d7SDag-Erling Smørgrav * the string */ 548*7b5038d7SDag-Erling Smørgrav 549*7b5038d7SDag-Erling Smørgrav *p = *++s; /* skip it */ 550*7b5038d7SDag-Erling Smørgrav (*length)++; 551*7b5038d7SDag-Erling Smørgrav /* I'm not sure if this is needed in libdns... MG */ 552*7b5038d7SDag-Erling Smørgrav if ( *s == '\0' ) { 553*7b5038d7SDag-Erling Smørgrav /* ok, it was the last one */ 554*7b5038d7SDag-Erling Smørgrav *p = '\0'; 555*7b5038d7SDag-Erling Smørgrav return LDNS_STATUS_OK; 556*7b5038d7SDag-Erling Smørgrav } 557*7b5038d7SDag-Erling Smørgrav break; 558*7b5038d7SDag-Erling Smørgrav default: 559*7b5038d7SDag-Erling Smørgrav *p = *s; 560*7b5038d7SDag-Erling Smørgrav (*length)++; 561*7b5038d7SDag-Erling Smørgrav break; 562*7b5038d7SDag-Erling Smørgrav } 563*7b5038d7SDag-Erling Smørgrav } 564*7b5038d7SDag-Erling Smørgrav *p = '\0'; 565*7b5038d7SDag-Erling Smørgrav return LDNS_STATUS_OK; 566*7b5038d7SDag-Erling Smørgrav } 567*7b5038d7SDag-Erling Smørgrav 568*7b5038d7SDag-Erling Smørgrav int 569*7b5038d7SDag-Erling Smørgrav ldns_rdf_compare(const ldns_rdf *rd1, const ldns_rdf *rd2) 570*7b5038d7SDag-Erling Smørgrav { 571*7b5038d7SDag-Erling Smørgrav uint16_t i1, i2, i; 572*7b5038d7SDag-Erling Smørgrav uint8_t *d1, *d2; 573*7b5038d7SDag-Erling Smørgrav 574*7b5038d7SDag-Erling Smørgrav /* only when both are not NULL we can say anything about them */ 575*7b5038d7SDag-Erling Smørgrav if (!rd1 && !rd2) { 576*7b5038d7SDag-Erling Smørgrav return 0; 577*7b5038d7SDag-Erling Smørgrav } 578*7b5038d7SDag-Erling Smørgrav if (!rd1 || !rd2) { 579*7b5038d7SDag-Erling Smørgrav return -1; 580*7b5038d7SDag-Erling Smørgrav } 581*7b5038d7SDag-Erling Smørgrav i1 = ldns_rdf_size(rd1); 582*7b5038d7SDag-Erling Smørgrav i2 = ldns_rdf_size(rd2); 583*7b5038d7SDag-Erling Smørgrav 584*7b5038d7SDag-Erling Smørgrav if (i1 < i2) { 585*7b5038d7SDag-Erling Smørgrav return -1; 586*7b5038d7SDag-Erling Smørgrav } else if (i1 > i2) { 587*7b5038d7SDag-Erling Smørgrav return +1; 588*7b5038d7SDag-Erling Smørgrav } else { 589*7b5038d7SDag-Erling Smørgrav d1 = (uint8_t*)ldns_rdf_data(rd1); 590*7b5038d7SDag-Erling Smørgrav d2 = (uint8_t*)ldns_rdf_data(rd2); 591*7b5038d7SDag-Erling Smørgrav for(i = 0; i < i1; i++) { 592*7b5038d7SDag-Erling Smørgrav if (d1[i] < d2[i]) { 593*7b5038d7SDag-Erling Smørgrav return -1; 594*7b5038d7SDag-Erling Smørgrav } else if (d1[i] > d2[i]) { 595*7b5038d7SDag-Erling Smørgrav return +1; 596*7b5038d7SDag-Erling Smørgrav } 597*7b5038d7SDag-Erling Smørgrav } 598*7b5038d7SDag-Erling Smørgrav } 599*7b5038d7SDag-Erling Smørgrav return 0; 600*7b5038d7SDag-Erling Smørgrav } 601*7b5038d7SDag-Erling Smørgrav 602*7b5038d7SDag-Erling Smørgrav uint32_t 603*7b5038d7SDag-Erling Smørgrav ldns_str2period(const char *nptr, const char **endptr) 604*7b5038d7SDag-Erling Smørgrav { 605*7b5038d7SDag-Erling Smørgrav int sign = 0; 606*7b5038d7SDag-Erling Smørgrav uint32_t i = 0; 607*7b5038d7SDag-Erling Smørgrav uint32_t seconds = 0; 608*7b5038d7SDag-Erling Smørgrav 609*7b5038d7SDag-Erling Smørgrav for(*endptr = nptr; **endptr; (*endptr)++) { 610*7b5038d7SDag-Erling Smørgrav switch (**endptr) { 611*7b5038d7SDag-Erling Smørgrav case ' ': 612*7b5038d7SDag-Erling Smørgrav case '\t': 613*7b5038d7SDag-Erling Smørgrav break; 614*7b5038d7SDag-Erling Smørgrav case '-': 615*7b5038d7SDag-Erling Smørgrav if(sign == 0) { 616*7b5038d7SDag-Erling Smørgrav sign = -1; 617*7b5038d7SDag-Erling Smørgrav } else { 618*7b5038d7SDag-Erling Smørgrav return seconds; 619*7b5038d7SDag-Erling Smørgrav } 620*7b5038d7SDag-Erling Smørgrav break; 621*7b5038d7SDag-Erling Smørgrav case '+': 622*7b5038d7SDag-Erling Smørgrav if(sign == 0) { 623*7b5038d7SDag-Erling Smørgrav sign = 1; 624*7b5038d7SDag-Erling Smørgrav } else { 625*7b5038d7SDag-Erling Smørgrav return seconds; 626*7b5038d7SDag-Erling Smørgrav } 627*7b5038d7SDag-Erling Smørgrav break; 628*7b5038d7SDag-Erling Smørgrav case 's': 629*7b5038d7SDag-Erling Smørgrav case 'S': 630*7b5038d7SDag-Erling Smørgrav seconds += i; 631*7b5038d7SDag-Erling Smørgrav i = 0; 632*7b5038d7SDag-Erling Smørgrav break; 633*7b5038d7SDag-Erling Smørgrav case 'm': 634*7b5038d7SDag-Erling Smørgrav case 'M': 635*7b5038d7SDag-Erling Smørgrav seconds += i * 60; 636*7b5038d7SDag-Erling Smørgrav i = 0; 637*7b5038d7SDag-Erling Smørgrav break; 638*7b5038d7SDag-Erling Smørgrav case 'h': 639*7b5038d7SDag-Erling Smørgrav case 'H': 640*7b5038d7SDag-Erling Smørgrav seconds += i * 60 * 60; 641*7b5038d7SDag-Erling Smørgrav i = 0; 642*7b5038d7SDag-Erling Smørgrav break; 643*7b5038d7SDag-Erling Smørgrav case 'd': 644*7b5038d7SDag-Erling Smørgrav case 'D': 645*7b5038d7SDag-Erling Smørgrav seconds += i * 60 * 60 * 24; 646*7b5038d7SDag-Erling Smørgrav i = 0; 647*7b5038d7SDag-Erling Smørgrav break; 648*7b5038d7SDag-Erling Smørgrav case 'w': 649*7b5038d7SDag-Erling Smørgrav case 'W': 650*7b5038d7SDag-Erling Smørgrav seconds += i * 60 * 60 * 24 * 7; 651*7b5038d7SDag-Erling Smørgrav i = 0; 652*7b5038d7SDag-Erling Smørgrav break; 653*7b5038d7SDag-Erling Smørgrav case '0': 654*7b5038d7SDag-Erling Smørgrav case '1': 655*7b5038d7SDag-Erling Smørgrav case '2': 656*7b5038d7SDag-Erling Smørgrav case '3': 657*7b5038d7SDag-Erling Smørgrav case '4': 658*7b5038d7SDag-Erling Smørgrav case '5': 659*7b5038d7SDag-Erling Smørgrav case '6': 660*7b5038d7SDag-Erling Smørgrav case '7': 661*7b5038d7SDag-Erling Smørgrav case '8': 662*7b5038d7SDag-Erling Smørgrav case '9': 663*7b5038d7SDag-Erling Smørgrav i *= 10; 664*7b5038d7SDag-Erling Smørgrav i += (**endptr - '0'); 665*7b5038d7SDag-Erling Smørgrav break; 666*7b5038d7SDag-Erling Smørgrav default: 667*7b5038d7SDag-Erling Smørgrav seconds += i; 668*7b5038d7SDag-Erling Smørgrav /* disregard signedness */ 669*7b5038d7SDag-Erling Smørgrav return seconds; 670*7b5038d7SDag-Erling Smørgrav } 671*7b5038d7SDag-Erling Smørgrav } 672*7b5038d7SDag-Erling Smørgrav seconds += i; 673*7b5038d7SDag-Erling Smørgrav /* disregard signedness */ 674*7b5038d7SDag-Erling Smørgrav return seconds; 675*7b5038d7SDag-Erling Smørgrav } 676