aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenys Vlasenko <vda.linux@googlemail.com>2018-08-01 19:42:46 +0200
committerDenys Vlasenko <vda.linux@googlemail.com>2018-08-01 19:42:46 +0200
commit9408978a438ac6c3becb2216d663216d27b59eab (patch)
tree5f5e4be84543ba3b91570d7cab3f2e9a673a97c8
parentd01c9aa7ca949220e76d28972359f97dd0b040b1 (diff)
downloadbusybox-w32-9408978a438ac6c3becb2216d663216d27b59eab.tar.gz
busybox-w32-9408978a438ac6c3becb2216d663216d27b59eab.tar.bz2
busybox-w32-9408978a438ac6c3becb2216d663216d27b59eab.zip
nslookup: add support for search domains, closes 11161
function old new delta parse_resolvconf - 311 +311 add_query_with_search - 105 +105 nslookup_main 873 757 -116 ------------------------------------------------------------------------------ (add/remove: 2/0 grow/shrink: 0/1 up/down: 416/-116) Total: 300 bytes Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-rw-r--r--networking/nslookup.c104
1 files changed, 82 insertions, 22 deletions
diff --git a/networking/nslookup.c b/networking/nslookup.c
index 3a614b0c6..e153eb585 100644
--- a/networking/nslookup.c
+++ b/networking/nslookup.c
@@ -318,6 +318,8 @@ struct globals {
318 unsigned serv_count; 318 unsigned serv_count;
319 struct ns *server; 319 struct ns *server;
320 struct query *query; 320 struct query *query;
321 char *search;
322 smalluint have_search_directive;
321} FIX_ALIASING; 323} FIX_ALIASING;
322#define G (*(struct globals*)bb_common_bufsiz1) 324#define G (*(struct globals*)bb_common_bufsiz1)
323#define INIT_G() do { \ 325#define INIT_G() do { \
@@ -667,24 +669,60 @@ static void parse_resolvconf(void)
667 669
668 resolv = fopen("/etc/resolv.conf", "r"); 670 resolv = fopen("/etc/resolv.conf", "r");
669 if (resolv) { 671 if (resolv) {
670 char line[128], *p; 672 char line[512]; /* "search" is defined to be up to 256 chars */
671 673
672 while (fgets(line, sizeof(line), resolv)) { 674 while (fgets(line, sizeof(line), resolv)) {
673 p = strtok(line, " \t\n"); 675 char *p, *arg;
674 676
675 if (!p || strcmp(p, "nameserver") != 0) 677 p = strtok(line, " \t\n");
678 if (!p)
679 continue;
680 dbg("resolv_key:'%s'\n", p);
681 arg = strtok(NULL, "\n");
682 dbg("resolv_arg:'%s'\n", arg);
683 if (!arg)
676 continue; 684 continue;
677 685
678 p = strtok(NULL, " \t\n"); 686 if (strcmp(p, "domain") == 0) {
687 /* domain DOM */
688 if (!G.have_search_directive)
689 goto set_search;
690 continue;
691 }
692 if (strcmp(p, "search") == 0) {
693 /* search DOM1 DOM2... */
694 G.have_search_directive = 1;
695 set_search:
696 free(G.search);
697 G.search = xstrdup(arg);
698 dbg("search='%s'\n", G.search);
699 continue;
700 }
679 701
680 if (!p) 702 if (strcmp(p, "nameserver") != 0)
681 continue; 703 continue;
682 704
683 add_ns(xstrdup(p)); 705 /* nameserver DNS */
706 add_ns(xstrdup(arg));
684 } 707 }
685 708
686 fclose(resolv); 709 fclose(resolv);
687 } 710 }
711
712 if (!G.search) {
713 /* default search domain is domain part of hostname */
714 char *h = safe_gethostname();
715 char *d = strchr(h, '.');
716 if (d) {
717 G.search = d + 1;
718 dbg("search='%s' (from hostname)\n", G.search);
719 }
720 /* else free(h); */
721 }
722
723 /* Cater for case of "domain ." in resolv.conf */
724 if (G.search && LONE_CHAR(G.search, '.'))
725 G.search = NULL;
688} 726}
689 727
690static void add_query(int type, const char *dname) 728static void add_query(int type, const char *dname)
@@ -695,7 +733,7 @@ static void add_query(int type, const char *dname)
695 733
696 count = G.query_count++; 734 count = G.query_count++;
697 735
698 G.query = xrealloc_vector(G.query, /*2=2^1:*/ 1, count); 736 G.query = xrealloc_vector(G.query, /*4=2^2:*/ 2, count);
699 new_q = &G.query[count]; 737 new_q = &G.query[count];
700 738
701 dbg("new query#%u type %u for '%s'\n", count, type, dname); 739 dbg("new query#%u type %u for '%s'\n", count, type, dname);
@@ -709,6 +747,28 @@ static void add_query(int type, const char *dname)
709 new_q->qlen = qlen; 747 new_q->qlen = qlen;
710} 748}
711 749
750static void add_query_with_search(int type, const char *dname)
751{
752 char *s;
753
754 if (type == T_PTR || !G.search || strchr(dname, '.')) {
755 add_query(type, dname);
756 return;
757 }
758
759 s = G.search;
760 for (;;) {
761 char *fullname, *e;
762
763 e = skip_non_whitespace(s);
764 fullname = xasprintf("%s.%.*s", dname, (int)(e - s), s);
765 add_query(type, fullname);
766 s = skip_whitespace(e);
767 if (!*s)
768 break;
769 }
770}
771
712static char *make_ptr(const char *addrstr) 772static char *make_ptr(const char *addrstr)
713{ 773{
714 unsigned char addr[16]; 774 unsigned char addr[16];
@@ -833,6 +893,18 @@ int nslookup_main(int argc UNUSED_PARAM, char **argv)
833 } 893 }
834 } 894 }
835 895
896 /* Use given DNS server if present */
897 if (argv[1]) {
898 if (argv[2])
899 bb_show_usage();
900 add_ns(argv[1]);
901 } else {
902 parse_resolvconf();
903 /* Fall back to localhost if we could not find NS in resolv.conf */
904 if (G.serv_count == 0)
905 add_ns("127.0.0.1");
906 }
907
836 if (types == 0) { 908 if (types == 0) {
837 /* No explicit type given, guess query type. 909 /* No explicit type given, guess query type.
838 * If we can convert the domain argument into a ptr (means that 910 * If we can convert the domain argument into a ptr (means that
@@ -846,31 +918,19 @@ int nslookup_main(int argc UNUSED_PARAM, char **argv)
846 if (ptr) { 918 if (ptr) {
847 add_query(T_PTR, ptr); 919 add_query(T_PTR, ptr);
848 } else { 920 } else {
849 add_query(T_A, argv[0]); 921 add_query_with_search(T_A, argv[0]);
850#if ENABLE_FEATURE_IPV6 922#if ENABLE_FEATURE_IPV6
851 add_query(T_AAAA, argv[0]); 923 add_query_with_search(T_AAAA, argv[0]);
852#endif 924#endif
853 } 925 }
854 } else { 926 } else {
855 int c; 927 int c;
856 for (c = 0; c < ARRAY_SIZE(qtypes); c++) { 928 for (c = 0; c < ARRAY_SIZE(qtypes); c++) {
857 if (types & (1 << c)) 929 if (types & (1 << c))
858 add_query(qtypes[c].type, argv[0]); 930 add_query_with_search(qtypes[c].type, argv[0]);
859 } 931 }
860 } 932 }
861 933
862 /* Use given DNS server if present */
863 if (argv[1]) {
864 if (argv[2])
865 bb_show_usage();
866 add_ns(argv[1]);
867 } else {
868 parse_resolvconf();
869 /* Fall back to localhost if we could not find NS in resolv.conf */
870 if (G.serv_count == 0)
871 add_ns("127.0.0.1");
872 }
873
874 for (rc = 0; rc < G.serv_count;) { 934 for (rc = 0; rc < G.serv_count;) {
875 int c; 935 int c;
876 936