char * strip_linefeeds(char *line) { char *p; if (line == NULL || strlen(line) == 0) return(line); p = &LASTCHAR(line); while (*p == '\n') *p = '\0'; return(line); }
/************************************************************************************************** AXFR_ZONE DNS-based zone transfer. **************************************************************************************************/ static void axfr_zone(TASK *t, MYDNS_SOA *soa) { /* Check optional "xfer" column and initialize reply */ check_xfer(t, soa); reply_init(t); /* Send opening SOA record */ rrlist_add(t, ANSWER, DNS_RRTYPE_SOA, (void *)soa, soa->origin); axfr_reply(t); /* ** Get all resource records for zone (if zone ID is nonzero, i.e. not manufactured) ** and transmit each resource record. */ if (soa->id) { MYDNS_RR *ThisRR = NULL, *rr = NULL; if (mydns_rr_load_active(sql, &ThisRR, soa->id, DNS_QTYPE_ANY, NULL, soa->origin) == 0) { for (rr = ThisRR; rr; rr = rr->next) { /* If 'name' doesn't end with a dot, append the origin */ if (!*MYDNS_RR_NAME(rr) || LASTCHAR(MYDNS_RR_NAME(rr)) != '.') { mydns_rr_name_append_origin(rr, soa->origin); } #if ALIAS_ENABLED /* * If we have been compiled with alias support * and the current record is an alias pass it to alias_recurse() */ if (rr->alias != 0) alias_recurse(t, ANSWER, MYDNS_RR_NAME(rr), soa, NULL, rr); else #endif rrlist_add(t, ANSWER, DNS_RRTYPE_RR, (void *)rr, MYDNS_RR_NAME(rr)); /* Transmit this resource record */ axfr_reply(t); } mydns_rr_free(ThisRR); } } /* Send closing SOA record */ rrlist_add(t, ANSWER, DNS_RRTYPE_SOA, (void *)soa, soa->origin); axfr_reply(t); mydns_soa_free(soa); }
static SEXP stripchars(const char * const inchar, int minlen) { /* This routine used to use strcpy with overlapping dest and src. That is not allowed by ISO C. */ int i, j, nspace = 0, upper; char *buff1 = cbuff.data; mystrcpy(buff1, inchar); upper = (int)(strlen(buff1) - 1); /* remove leading blanks */ j = 0; for (i = 0 ; i < upper ; i++) if (isspace((int)buff1[i])) j++; else break; mystrcpy(buff1, &buff1[j]); upper = (int)(strlen(buff1) - 1); if (strlen(buff1) < minlen) goto donesc; for (i = upper, j = 1; i > 0; i--) { if (isspace((int)buff1[i])) { if (j) buff1[i] = '\0' ; else nspace++; } else j = 0; /*strcpy(buff1[i],buff1[i+1]);*/ if (strlen(buff1) - nspace <= minlen) goto donesc; } upper = (int)(strlen(buff1) - 1); for (i = upper; i > 0; i--) { if (LOWVOW(i) && LASTCHAR(i)) mystrcpy(&buff1[i], &buff1[i + 1]); if (strlen(buff1) - nspace <= minlen) goto donesc; } upper = (int)(strlen(buff1) - 1); for (i = upper; i > 0; i--) { if (LOWVOW(i) && !FIRSTCHAR(i)) mystrcpy(&buff1[i], &buff1[i + 1]); if (strlen(buff1) - nspace <= minlen) goto donesc; } upper = (int)(strlen(buff1) - 1); for (i = upper; i > 0; i--) { if (islower((int)buff1[i]) && LASTCHAR(i)) mystrcpy(&buff1[i], &buff1[i + 1]); if (strlen(buff1) - nspace <= minlen) goto donesc; } upper = (int)(strlen(buff1) - 1); for (i = upper; i > 0; i--) { if (islower((int)buff1[i]) && !FIRSTCHAR(i)) mystrcpy(&buff1[i], &buff1[i + 1]); if (strlen(buff1) - nspace <= minlen) goto donesc; } /* all else has failed so we use brute force */ upper = (int)(strlen(buff1) - 1); for (i = upper; i > 0; i--) { if (!FIRSTCHAR(i) && !isspace((int)buff1[i])) mystrcpy(&buff1[i], &buff1[i + 1]); if (strlen(buff1) - nspace <= minlen) goto donesc; } donesc: upper = (int) strlen(buff1); if (upper > minlen) for (i = upper - 1; i > 0; i--) if (isspace((int)buff1[i])) mystrcpy(&buff1[i], &buff1[i + 1]); return(mkChar(buff1)); }
/************************************************************************************************** ALIAS_RECURSE If the task has a matching ALIAS record, recurse into it. Returns the number of records added. **************************************************************************************************/ int alias_recurse(TASK *t, datasection_t section, char *fqdn, MYDNS_SOA *soa, char *label, MYDNS_RR *alias) { uint32_t aliases[MAX_ALIAS_LEVEL]; char name[DNS_MAXNAMELEN+1]; register MYDNS_RR *rr; register int depth, n; if (LASTCHAR(alias->data) != '.') snprintf(name, sizeof(name), "%s.%s", alias->data, soa->origin); else strncpy(name, alias->data, sizeof(name)-1); for (depth = 0; depth < MAX_ALIAS_LEVEL; depth++) { #if DEBUG_ENABLED && DEBUG_ALIAS Debug("%s: ALIAS -> `%s'", desctask(t), name); #endif /* Are there any alias records? */ if ((rr = find_alias(t, name))) { /* We need an A record that is not an alias to end the chain. */ if (rr->alias == 0) { /* Override the id and name, because rrlist_add() checks for duplicates and we might have several records aliased to one */ rr->id = alias->id; strcpy(rr->name, alias->name); rrlist_add(t, section, DNS_RRTYPE_RR, (void *)rr, fqdn); t->sort_level++; mydns_rr_free(rr); return (1); } /* Append origin if needed */ int len = strlen(rr->data); if (len > 0 && rr->data[len - 1] != '.') { strcat(rr->data, "."); strncat(rr->data, soa->origin, sizeof(rr->name) - len - 1); } /* Check aliases list; if we are looping, stop. Otherwise add this to the list. */ for (n = 0; n < depth; n++) if (aliases[n] == rr->id) { /* ALIAS loop: We aren't going to find an A record, so we're done. */ Verbose("%s: %s: %s (depth %d)", desctask(t), _("ALIAS loop detected"), fqdn, depth); mydns_rr_free(rr); return (0); } aliases[depth] = rr->id; /* Continue search with new alias. */ strncpy(name, rr->data, sizeof(name)-1); mydns_rr_free(rr); } else { Verbose("%s: %s: %s -> %s", desctask(t), _("ALIAS chain is broken"), fqdn, name); return (0); } } Verbose("%s: %s: %s -> %s (depth %d)", desctask(t), _("max ALIAS depth exceeded"), fqdn, alias->data, depth); return (0); }