1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* This Source Code Form is subject to the terms of the Mozilla Public
3  * License, v. 2.0. If a copy of the MPL was not distributed with this
4  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
5 
6 #include "prio.h"
7 #include "prenv.h"
8 #include "prmem.h"
9 #include "prlink.h"
10 #include "prsystem.h"
11 #include "prnetdb.h"
12 #include "prprf.h"
13 #include "prvrsion.h"
14 
15 #include "plerror.h"
16 #include "plgetopt.h"
17 #include "obsolete/probslet.h"
18 
19 #include <string.h>
20 
21 #define DNS_BUFFER 100
22 #define ADDR_BUFFER 100
23 #define HOST_BUFFER 1024
24 #define PROTO_BUFFER 1500
25 
26 #define NETADDR_SIZE(addr) \
27     (PR_AF_INET == (addr)->raw.family ? \
28     sizeof((addr)->inet) : sizeof((addr)->ipv6))
29 
30 static PRFileDesc *err = NULL;
31 
Help(void)32 static void Help(void)
33 {
34     PR_fprintf(err, "Usage: [-V] [-h]\n");
35     PR_fprintf(err, "\t<nul>    Name of host to lookup          (default: self)\n");
36     PR_fprintf(err, "\t-V       Display runtime version info    (default: FALSE)\n");
37     PR_fprintf(err, "\t-h       This message and nothing else\n");
38 }  /* Help */
39 
DumpAddr(const PRNetAddr * address,const char * msg)40 static void DumpAddr(const PRNetAddr* address, const char *msg)
41 {
42     PRUint32 *word = (PRUint32*)address;
43     PRUint32 addr_len = sizeof(PRNetAddr);
44     PR_fprintf(err, "%s[%d]\t", msg, NETADDR_SIZE(address));
45     while (addr_len > 0)
46     {
47         PR_fprintf(err, " %08x", *word++);
48         addr_len -= sizeof(PRUint32);
49     }
50     PR_fprintf(err, "\n");
51 }  /* DumpAddr */
52 
PrintAddress(const PRNetAddr * address)53 static PRStatus PrintAddress(const PRNetAddr* address)
54 {
55     PRNetAddr translation;
56     char buffer[ADDR_BUFFER];
57     PRStatus rv = PR_NetAddrToString(address, buffer, sizeof(buffer));
58     if (PR_FAILURE == rv) PL_FPrintError(err, "PR_NetAddrToString");
59     else
60     {
61         PR_fprintf(err, "\t%s\n", buffer);
62         memset(&translation, 0, sizeof(translation));
63         rv = PR_StringToNetAddr(buffer, &translation);
64         if (PR_FAILURE == rv) PL_FPrintError(err, "PR_StringToNetAddr");
65         else
66         {
67             PRSize addr_len = NETADDR_SIZE(address);
68             if (0 != memcmp(address, &translation, addr_len))
69             {
70                 PR_fprintf(err, "Address translations do not match\n");
71                 DumpAddr(address, "original");
72                 DumpAddr(&translation, "translate");
73                 rv = PR_FAILURE;
74             }
75         }
76     }
77     return rv;
78 }  /* PrintAddress */
79 
main(int argc,char ** argv)80 int main(int argc, char **argv)
81 {
82     PRStatus rv;
83     PLOptStatus os;
84     PRHostEnt host;
85     PRProtoEnt proto;
86     const char *name = NULL;
87     PRBool failed = PR_FALSE, version = PR_FALSE;
88     PLOptState *opt = PL_CreateOptState(argc, argv, "Vh");
89 
90     err = PR_GetSpecialFD(PR_StandardError);
91 
92     while (PL_OPT_EOL != (os = PL_GetNextOpt(opt)))
93     {
94         if (PL_OPT_BAD == os) continue;
95         switch (opt->option)
96         {
97         case 0:  /* Name of host to lookup */
98             name = opt->value;
99             break;
100          case 'V':  /* Do version discovery */
101             version = PR_TRUE;
102             break;
103         case 'h':  /* user wants some guidance */
104          default:
105             Help();  /* so give him an earful */
106             return 2;  /* but not a lot else */
107         }
108     }
109     PL_DestroyOptState(opt);
110 
111     if (version)
112     {
113 #if defined(WINNT)
114 #define NSPR_LIB "libnspr4"
115 #else
116 #define NSPR_LIB "nspr4"
117 #endif
118         const PRVersionDescription *version_info;
119         char *nspr_path = PR_GetEnv("LD_LIBRARY_PATH");
120         char *nspr_name = PR_GetLibraryName(nspr_path, NSPR_LIB);
121         PRLibrary *runtime = PR_LoadLibrary(nspr_name);
122         if (NULL == runtime)
123             PL_FPrintError(err, "PR_LoadLibrary");
124         else
125         {
126             versionEntryPointType versionPoint = (versionEntryPointType)
127                 PR_FindSymbol(runtime, "libVersionPoint");
128             if (NULL == versionPoint)
129                 PL_FPrintError(err, "PR_FindSymbol");
130             else
131             {
132                 char buffer[100];
133                 PRExplodedTime exploded;
134                 version_info = versionPoint();
135                 (void)PR_fprintf(err, "Runtime library version information\n");
136                 PR_ExplodeTime(
137                     version_info->buildTime, PR_GMTParameters, &exploded);
138                 (void)PR_FormatTime(
139                     buffer, sizeof(buffer), "%d %b %Y %H:%M:%S", &exploded);
140                 (void)PR_fprintf(err, "  Build time: %s GMT\n", buffer);
141                 (void)PR_fprintf(
142                     err, "  Build time: %s\n", version_info->buildTimeString);
143                 (void)PR_fprintf(
144                     err, "  %s V%u.%u.%u (%s%s%s)\n",
145                     version_info->description,
146                     version_info->vMajor,
147                     version_info->vMinor,
148                     version_info->vPatch,
149                     (version_info->beta ? " beta " : ""),
150                     (version_info->debug ? " debug " : ""),
151                     (version_info->special ? " special" : ""));
152                 (void)PR_fprintf(err, "  filename: %s\n", version_info->filename);
153                 (void)PR_fprintf(err, "  security: %s\n", version_info->security);
154                 (void)PR_fprintf(err, "  copyright: %s\n", version_info->copyright);
155                 (void)PR_fprintf(err, "  comment: %s\n", version_info->comment);
156             }
157         }
158         if (NULL != nspr_name) PR_FreeLibraryName(nspr_name);
159     }
160 
161     {
162         if (NULL == name)
163         {
164             char *me = (char*)PR_MALLOC(DNS_BUFFER);
165             rv = PR_GetSystemInfo(PR_SI_HOSTNAME, me, DNS_BUFFER);
166             if (PR_FAILURE == rv)
167             {
168                 failed = PR_TRUE;
169                 PL_FPrintError(err, "PR_GetSystemInfo");
170                 return 2;
171             }
172             name = me;  /* just leak the storage */
173         }
174     }
175 
176     {
177         char buffer[HOST_BUFFER];
178         PR_fprintf(err, "Translating the name %s ...", name);
179 
180         rv = PR_GetHostByName(name, buffer, sizeof(buffer), &host);
181         if (PR_FAILURE == rv)
182         {
183             failed = PR_TRUE;
184             PL_FPrintError(err, "PR_GetHostByName");
185         }
186         else
187         {
188             PRIntn index = 0;
189             PRNetAddr address;
190             memset(&address, 0, sizeof(PRNetAddr));
191             PR_fprintf(err, "success .. enumerating results\n");
192             do
193             {
194                 index = PR_EnumerateHostEnt(index, &host, 0, &address);
195                 if (index > 0) PrintAddress(&address);
196                 else if (-1 == index)
197                 {
198                     failed = PR_TRUE;
199                     PL_FPrintError(err, "PR_EnumerateHostEnt");
200                 }
201             } while (index > 0);
202         }
203     }
204 
205 
206     {
207         char buffer[PROTO_BUFFER];
208         /*
209         ** Get Proto by name/number
210         */
211         rv = PR_GetProtoByName("tcp", &buffer[1], sizeof(buffer) - 1, &proto);
212         rv = PR_GetProtoByNumber(6, &buffer[3], sizeof(buffer) - 3, &proto);
213     }
214 
215     return (failed) ? 1 : 0;
216 }
217