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) {
59         PL_FPrintError(err, "PR_NetAddrToString");
60     }
61     else
62     {
63         PR_fprintf(err, "\t%s\n", buffer);
64         memset(&translation, 0, sizeof(translation));
65         rv = PR_StringToNetAddr(buffer, &translation);
66         if (PR_FAILURE == rv) {
67             PL_FPrintError(err, "PR_StringToNetAddr");
68         }
69         else
70         {
71             PRSize addr_len = NETADDR_SIZE(address);
72             if (0 != memcmp(address, &translation, addr_len))
73             {
74                 PR_fprintf(err, "Address translations do not match\n");
75                 DumpAddr(address, "original");
76                 DumpAddr(&translation, "translate");
77                 rv = PR_FAILURE;
78             }
79         }
80     }
81     return rv;
82 }  /* PrintAddress */
83 
main(int argc,char ** argv)84 int main(int argc, char **argv)
85 {
86     PRStatus rv;
87     PLOptStatus os;
88     PRHostEnt host;
89     PRProtoEnt proto;
90     const char *name = NULL;
91     PRBool failed = PR_FALSE, version = PR_FALSE;
92     PLOptState *opt = PL_CreateOptState(argc, argv, "Vh");
93 
94     err = PR_GetSpecialFD(PR_StandardError);
95 
96     while (PL_OPT_EOL != (os = PL_GetNextOpt(opt)))
97     {
98         if (PL_OPT_BAD == os) {
99             continue;
100         }
101         switch (opt->option)
102         {
103             case 0:  /* Name of host to lookup */
104                 name = opt->value;
105                 break;
106             case 'V':  /* Do version discovery */
107                 version = PR_TRUE;
108                 break;
109             case 'h':  /* user wants some guidance */
110             default:
111                 Help();  /* so give him an earful */
112                 return 2;  /* but not a lot else */
113         }
114     }
115     PL_DestroyOptState(opt);
116 
117     if (version)
118     {
119 #if defined(WINNT)
120 #define NSPR_LIB "libnspr4"
121 #else
122 #define NSPR_LIB "nspr4"
123 #endif
124         const PRVersionDescription *version_info;
125         char *nspr_path = PR_GetEnv("LD_LIBRARY_PATH");
126         char *nspr_name = PR_GetLibraryName(nspr_path, NSPR_LIB);
127         PRLibrary *runtime = PR_LoadLibrary(nspr_name);
128         if (NULL == runtime) {
129             PL_FPrintError(err, "PR_LoadLibrary");
130         }
131         else
132         {
133             versionEntryPointType versionPoint = (versionEntryPointType)
134                                                  PR_FindSymbol(runtime, "libVersionPoint");
135             if (NULL == versionPoint) {
136                 PL_FPrintError(err, "PR_FindSymbol");
137             }
138             else
139             {
140                 char buffer[100];
141                 PRExplodedTime exploded;
142                 version_info = versionPoint();
143                 (void)PR_fprintf(err, "Runtime library version information\n");
144                 PR_ExplodeTime(
145                     version_info->buildTime, PR_GMTParameters, &exploded);
146                 (void)PR_FormatTime(
147                     buffer, sizeof(buffer), "%d %b %Y %H:%M:%S", &exploded);
148                 (void)PR_fprintf(err, "  Build time: %s GMT\n", buffer);
149                 (void)PR_fprintf(
150                     err, "  Build time: %s\n", version_info->buildTimeString);
151                 (void)PR_fprintf(
152                     err, "  %s V%u.%u.%u (%s%s%s)\n",
153                     version_info->description,
154                     version_info->vMajor,
155                     version_info->vMinor,
156                     version_info->vPatch,
157                     (version_info->beta ? " beta " : ""),
158                     (version_info->debug ? " debug " : ""),
159                     (version_info->special ? " special" : ""));
160                 (void)PR_fprintf(err, "  filename: %s\n", version_info->filename);
161                 (void)PR_fprintf(err, "  security: %s\n", version_info->security);
162                 (void)PR_fprintf(err, "  copyright: %s\n", version_info->copyright);
163                 (void)PR_fprintf(err, "  comment: %s\n", version_info->comment);
164             }
165         }
166         if (NULL != nspr_name) {
167             PR_FreeLibraryName(nspr_name);
168         }
169     }
170 
171     {
172         if (NULL == name)
173         {
174             char *me = (char*)PR_MALLOC(DNS_BUFFER);
175             rv = PR_GetSystemInfo(PR_SI_HOSTNAME, me, DNS_BUFFER);
176             if (PR_FAILURE == rv)
177             {
178                 failed = PR_TRUE;
179                 PL_FPrintError(err, "PR_GetSystemInfo");
180                 return 2;
181             }
182             name = me;  /* just leak the storage */
183         }
184     }
185 
186     {
187         char buffer[HOST_BUFFER];
188         PR_fprintf(err, "Translating the name %s ...", name);
189 
190         rv = PR_GetHostByName(name, buffer, sizeof(buffer), &host);
191         if (PR_FAILURE == rv)
192         {
193             failed = PR_TRUE;
194             PL_FPrintError(err, "PR_GetHostByName");
195         }
196         else
197         {
198             PRIntn index = 0;
199             PRNetAddr address;
200             memset(&address, 0, sizeof(PRNetAddr));
201             PR_fprintf(err, "success .. enumerating results\n");
202             do
203             {
204                 index = PR_EnumerateHostEnt(index, &host, 0, &address);
205                 if (index > 0) {
206                     PrintAddress(&address);
207                 }
208                 else if (-1 == index)
209                 {
210                     failed = PR_TRUE;
211                     PL_FPrintError(err, "PR_EnumerateHostEnt");
212                 }
213             } while (index > 0);
214         }
215     }
216 
217 
218     {
219         char buffer[PROTO_BUFFER];
220         /*
221         ** Get Proto by name/number
222         */
223         rv = PR_GetProtoByName("tcp", &buffer[1], sizeof(buffer) - 1, &proto);
224         rv = PR_GetProtoByNumber(6, &buffer[3], sizeof(buffer) - 3, &proto);
225     }
226 
227     return (failed) ? 1 : 0;
228 }
229