1 | /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
---|
2 | /* ***** BEGIN LICENSE BLOCK *****
|
---|
3 | * Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
---|
4 | *
|
---|
5 | * The contents of this file are subject to the Mozilla Public License Version
|
---|
6 | * 1.1 (the "License"); you may not use this file except in compliance with
|
---|
7 | * the License. You may obtain a copy of the License at
|
---|
8 | * http://www.mozilla.org/MPL/
|
---|
9 | *
|
---|
10 | * Software distributed under the License is distributed on an "AS IS" basis,
|
---|
11 | * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
---|
12 | * for the specific language governing rights and limitations under the
|
---|
13 | * License.
|
---|
14 | *
|
---|
15 | * The Original Code is mozilla.org code.
|
---|
16 | *
|
---|
17 | * The Initial Developer of the Original Code is
|
---|
18 | * Netscape Communications Corporation.
|
---|
19 | * Portions created by the Initial Developer are Copyright (C) 1998
|
---|
20 | * the Initial Developer. All Rights Reserved.
|
---|
21 | *
|
---|
22 | * Contributor(s):
|
---|
23 | * Pierre Phaneuf <pp@ludusdesign.com>
|
---|
24 | * Mike Shaver <shaver@mozilla.org>
|
---|
25 | *
|
---|
26 | * Alternatively, the contents of this file may be used under the terms of
|
---|
27 | * either of the GNU General Public License Version 2 or later (the "GPL"),
|
---|
28 | * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
---|
29 | * in which case the provisions of the GPL or the LGPL are applicable instead
|
---|
30 | * of those above. If you wish to allow use of your version of this file only
|
---|
31 | * under the terms of either the GPL or the LGPL, and not to allow others to
|
---|
32 | * use your version of this file under the terms of the MPL, indicate your
|
---|
33 | * decision by deleting the provisions above and replace them with the notice
|
---|
34 | * and other provisions required by the GPL or the LGPL. If you do not delete
|
---|
35 | * the provisions above, a recipient may use your version of this file under
|
---|
36 | * the terms of any one of the MPL, the GPL or the LGPL.
|
---|
37 | *
|
---|
38 | * ***** END LICENSE BLOCK ***** */
|
---|
39 |
|
---|
40 | #include "stdlib.h"
|
---|
41 | #include "prenv.h"
|
---|
42 | #include "nspr.h"
|
---|
43 |
|
---|
44 | #include "nsXPCOMPrivate.h" // for XPCOM_DLL defines.
|
---|
45 |
|
---|
46 | #include "nsXPCOMGlue.h"
|
---|
47 | #include "nsIComponentManager.h"
|
---|
48 | #include "nsIComponentRegistrar.h"
|
---|
49 | #include "nsIServiceManager.h"
|
---|
50 | #include "nsCOMPtr.h"
|
---|
51 | #include "nsILocalFile.h"
|
---|
52 | #include "nsEmbedString.h"
|
---|
53 | #include "nsIDirectoryService.h"
|
---|
54 | #include "nsDirectoryServiceDefs.h"
|
---|
55 |
|
---|
56 |
|
---|
57 | static PRBool gUnreg = PR_FALSE, gQuiet = PR_FALSE;
|
---|
58 |
|
---|
59 | static const char* gXPCOMLocation = nsnull;
|
---|
60 | static const char* gCompRegLocation = nsnull;
|
---|
61 | static const char* gXPTIDatLocation = nsnull;
|
---|
62 | static char* gPathEnvString = nsnull;
|
---|
63 |
|
---|
64 | class DirectoryServiceProvider : public nsIDirectoryServiceProvider
|
---|
65 | {
|
---|
66 | public:
|
---|
67 | DirectoryServiceProvider() {}
|
---|
68 |
|
---|
69 | NS_DECL_ISUPPORTS
|
---|
70 | NS_DECL_NSIDIRECTORYSERVICEPROVIDER
|
---|
71 |
|
---|
72 | private:
|
---|
73 | ~DirectoryServiceProvider() {}
|
---|
74 | };
|
---|
75 |
|
---|
76 | NS_IMPL_ISUPPORTS1(DirectoryServiceProvider, nsIDirectoryServiceProvider)
|
---|
77 |
|
---|
78 | NS_IMETHODIMP
|
---|
79 | DirectoryServiceProvider::GetFile(const char *prop, PRBool *persistant, nsIFile **_retval)
|
---|
80 | {
|
---|
81 | nsCOMPtr<nsILocalFile> localFile;
|
---|
82 | nsresult rv = NS_ERROR_FAILURE;
|
---|
83 |
|
---|
84 | *_retval = nsnull;
|
---|
85 | *persistant = PR_TRUE;
|
---|
86 |
|
---|
87 | const char* fileLocation = nsnull;
|
---|
88 |
|
---|
89 | if(strcmp(prop, NS_XPCOM_CURRENT_PROCESS_DIR) == 0 && gXPCOMLocation)
|
---|
90 | {
|
---|
91 | fileLocation = gXPCOMLocation;
|
---|
92 | }
|
---|
93 | else if(strcmp(prop, NS_XPCOM_COMPONENT_REGISTRY_FILE) == 0 && gCompRegLocation)
|
---|
94 | {
|
---|
95 | fileLocation = gCompRegLocation;
|
---|
96 | }
|
---|
97 | else if(strcmp(prop, NS_XPCOM_XPTI_REGISTRY_FILE) == 0 && gXPTIDatLocation)
|
---|
98 | {
|
---|
99 | fileLocation = gXPTIDatLocation;
|
---|
100 | }
|
---|
101 | else
|
---|
102 | return NS_ERROR_FAILURE;
|
---|
103 |
|
---|
104 | rv = NS_NewNativeLocalFile(nsEmbedCString(fileLocation), PR_TRUE, getter_AddRefs(localFile));
|
---|
105 | if (NS_FAILED(rv)) return rv;
|
---|
106 |
|
---|
107 | return localFile->QueryInterface(NS_GET_IID(nsIFile), (void**)_retval);
|
---|
108 | }
|
---|
109 |
|
---|
110 | int startup_xpcom()
|
---|
111 | {
|
---|
112 | nsresult rv;
|
---|
113 |
|
---|
114 | if (gXPCOMLocation) {
|
---|
115 | int len = strlen(gXPCOMLocation);
|
---|
116 | char* xpcomPath = (char*) malloc(len + sizeof(XPCOM_DLL) + sizeof(XPCOM_FILE_PATH_SEPARATOR) + 1);
|
---|
117 | sprintf(xpcomPath, "%s" XPCOM_FILE_PATH_SEPARATOR XPCOM_DLL, gXPCOMLocation);
|
---|
118 |
|
---|
119 | rv = XPCOMGlueStartup(xpcomPath);
|
---|
120 |
|
---|
121 | free(xpcomPath);
|
---|
122 |
|
---|
123 | const char* path = PR_GetEnv(XPCOM_SEARCH_KEY);
|
---|
124 | if (!path) {
|
---|
125 | path = "";
|
---|
126 | }
|
---|
127 |
|
---|
128 | if (gPathEnvString)
|
---|
129 | PR_smprintf_free(gPathEnvString);
|
---|
130 |
|
---|
131 | gPathEnvString = PR_smprintf("%s=%s;%s",
|
---|
132 | XPCOM_SEARCH_KEY,
|
---|
133 | gXPCOMLocation,
|
---|
134 | path);
|
---|
135 |
|
---|
136 | if (gXPCOMLocation)
|
---|
137 | PR_SetEnv(gPathEnvString);
|
---|
138 | }
|
---|
139 | else
|
---|
140 | {
|
---|
141 | rv = XPCOMGlueStartup(nsnull);
|
---|
142 | }
|
---|
143 |
|
---|
144 | if (NS_FAILED(rv))
|
---|
145 | {
|
---|
146 | printf("Can not initialize XPCOM Glue\n");
|
---|
147 | return -1;
|
---|
148 | }
|
---|
149 |
|
---|
150 | DirectoryServiceProvider *provider = new DirectoryServiceProvider();
|
---|
151 | if ( !provider )
|
---|
152 | {
|
---|
153 | NS_WARNING("GRE_Startup failed");
|
---|
154 | XPCOMGlueShutdown();
|
---|
155 | return -1;
|
---|
156 | }
|
---|
157 |
|
---|
158 | nsCOMPtr<nsILocalFile> file;
|
---|
159 | if (gXPCOMLocation)
|
---|
160 | {
|
---|
161 | rv = NS_NewNativeLocalFile(nsEmbedCString(gXPCOMLocation),
|
---|
162 | PR_TRUE,
|
---|
163 | getter_AddRefs(file));
|
---|
164 | }
|
---|
165 |
|
---|
166 | NS_ADDREF(provider);
|
---|
167 | rv = NS_InitXPCOM2(nsnull, file, provider);
|
---|
168 | NS_RELEASE(provider);
|
---|
169 |
|
---|
170 | if (NS_FAILED(rv)) {
|
---|
171 | printf("Can not initialize XPCOM\n");
|
---|
172 | XPCOMGlueShutdown();
|
---|
173 | return -1;
|
---|
174 | }
|
---|
175 |
|
---|
176 | return 0;
|
---|
177 | }
|
---|
178 |
|
---|
179 | void shutdown_xpcom()
|
---|
180 | {
|
---|
181 | nsresult rv;
|
---|
182 |
|
---|
183 | rv = NS_ShutdownXPCOM(nsnull);
|
---|
184 |
|
---|
185 | if (NS_FAILED(rv)) {
|
---|
186 | printf("Can not shutdown XPCOM cleanly\n");
|
---|
187 | }
|
---|
188 |
|
---|
189 | rv = XPCOMGlueShutdown();
|
---|
190 |
|
---|
191 | if (NS_FAILED(rv)) {
|
---|
192 | printf("Can not shutdown XPCOM Glue cleanly\n");
|
---|
193 | }
|
---|
194 | if (gPathEnvString)
|
---|
195 | PR_smprintf_free(gPathEnvString);
|
---|
196 | }
|
---|
197 |
|
---|
198 |
|
---|
199 | nsresult Register(const char *path)
|
---|
200 | {
|
---|
201 | startup_xpcom();
|
---|
202 |
|
---|
203 | nsresult rv;
|
---|
204 | nsCOMPtr<nsILocalFile> spec;
|
---|
205 |
|
---|
206 | if (path) {
|
---|
207 | rv = NS_NewNativeLocalFile(nsEmbedCString(path),
|
---|
208 | PR_TRUE,
|
---|
209 | getter_AddRefs(spec));
|
---|
210 | }
|
---|
211 |
|
---|
212 | nsCOMPtr<nsIComponentRegistrar> registrar;
|
---|
213 | rv = NS_GetComponentRegistrar(getter_AddRefs(registrar));
|
---|
214 | if (NS_FAILED(rv)) {
|
---|
215 | printf("Can not aquire component registrar\n");
|
---|
216 | return rv;
|
---|
217 | }
|
---|
218 |
|
---|
219 | if (gUnreg)
|
---|
220 | rv = registrar->AutoUnregister(spec);
|
---|
221 | else
|
---|
222 | rv = registrar->AutoRegister(spec);
|
---|
223 |
|
---|
224 | spec = 0;
|
---|
225 | registrar = 0;
|
---|
226 |
|
---|
227 | shutdown_xpcom();
|
---|
228 | return rv;
|
---|
229 | }
|
---|
230 |
|
---|
231 |
|
---|
232 | void ReportSuccess(const char *file)
|
---|
233 | {
|
---|
234 | if (gQuiet)
|
---|
235 | return;
|
---|
236 |
|
---|
237 | if (gUnreg)
|
---|
238 | printf("Unregistration successful for %s\n", file);
|
---|
239 | else
|
---|
240 | printf("Registration successful for %s\n", file);
|
---|
241 | }
|
---|
242 |
|
---|
243 | void ReportError(nsresult err, const char *file)
|
---|
244 | {
|
---|
245 | if (gUnreg)
|
---|
246 | printf("Unregistration failed: (");
|
---|
247 | else
|
---|
248 | printf("Registration failed: (");
|
---|
249 |
|
---|
250 | switch (err)
|
---|
251 | {
|
---|
252 | case NS_ERROR_FACTORY_NOT_LOADED:
|
---|
253 | printf("Factory not loaded");
|
---|
254 | break;
|
---|
255 | case NS_NOINTERFACE:
|
---|
256 | printf("No Interface");
|
---|
257 | break;
|
---|
258 | case NS_ERROR_NULL_POINTER:
|
---|
259 | printf("Null pointer");
|
---|
260 | break;
|
---|
261 | case NS_ERROR_OUT_OF_MEMORY:
|
---|
262 | printf("Out of memory");
|
---|
263 | break;
|
---|
264 | default:
|
---|
265 | printf("%x", (unsigned)err);
|
---|
266 | }
|
---|
267 |
|
---|
268 | printf(") %s\n", file);
|
---|
269 | }
|
---|
270 |
|
---|
271 | void printHelp()
|
---|
272 | {
|
---|
273 | printf(
|
---|
274 | "Mozilla regxpcom - a registration tool for xpcom components \n"
|
---|
275 | " \n"
|
---|
276 | "Usage: regxpcom [options] [file-or-directory] \n"
|
---|
277 | " \n"
|
---|
278 | "Options: \n"
|
---|
279 | " -x path Specifies the location of a directory containing the \n"
|
---|
280 | " xpcom library which will be used when registering new \n"
|
---|
281 | " component libraries. This path will also be added to \n"
|
---|
282 | " the \"load library\" path. If not specified, the \n"
|
---|
283 | " current working directory will be used. \n"
|
---|
284 | " -c path Specifies the location of the compreg.dat file. If \n"
|
---|
285 | " not specifed, the compreg.dat file will be in its \n"
|
---|
286 | " default location. \n"
|
---|
287 | " -d path Specifies the location of the xpti.dat file. If not \n"
|
---|
288 | " specifed, the xpti.dat file will be in its default \n"
|
---|
289 | " location. \n"
|
---|
290 | " -a Option to register all files in the default component \n"
|
---|
291 | " directories. This is the default behavior if regxpcom \n"
|
---|
292 | " is called without any arguments. \n"
|
---|
293 | " -h Displays this help screen. Must be the only option \n"
|
---|
294 | " specified. \n"
|
---|
295 | " -u Option to uninstall the files-or-directory instead of \n"
|
---|
296 | " registering them. \n"
|
---|
297 | " -q Quiets some of the output of regxpcom. \n\n");
|
---|
298 | }
|
---|
299 |
|
---|
300 | int ProcessArgs(int argc, char *argv[])
|
---|
301 | {
|
---|
302 | int i = 1, result = 0;
|
---|
303 | nsresult res;
|
---|
304 |
|
---|
305 | while (i < argc)
|
---|
306 | {
|
---|
307 | if (argv[i][0] == '-')
|
---|
308 | {
|
---|
309 | int j;
|
---|
310 | for (j = 1; argv[i][j] != '\0'; j++)
|
---|
311 | {
|
---|
312 | switch (argv[i][j])
|
---|
313 | {
|
---|
314 | case 'h':
|
---|
315 | printHelp();
|
---|
316 | return 0; // we are all done!
|
---|
317 |
|
---|
318 | case 'u':
|
---|
319 | gUnreg = PR_TRUE;
|
---|
320 | break;
|
---|
321 |
|
---|
322 | case 'q':
|
---|
323 | gQuiet = PR_TRUE;
|
---|
324 | break;
|
---|
325 |
|
---|
326 | case 'a':
|
---|
327 | {
|
---|
328 | res = Register(nsnull);
|
---|
329 | if (NS_FAILED(res))
|
---|
330 | {
|
---|
331 | ReportError(res, "component directory");
|
---|
332 | result = -1;
|
---|
333 | }
|
---|
334 | else
|
---|
335 | {
|
---|
336 | ReportSuccess("component directory");
|
---|
337 | }
|
---|
338 | }
|
---|
339 | break;
|
---|
340 |
|
---|
341 | case 'x':
|
---|
342 | gXPCOMLocation = argv[++i];
|
---|
343 | j = strlen(gXPCOMLocation) - 1;
|
---|
344 | break;
|
---|
345 |
|
---|
346 | case 'c':
|
---|
347 | gCompRegLocation = argv[++i];
|
---|
348 | j = strlen(gCompRegLocation) - 1;
|
---|
349 | break;
|
---|
350 |
|
---|
351 | case 'd':
|
---|
352 | gXPTIDatLocation = argv[++i];
|
---|
353 | j = strlen(gXPTIDatLocation) - 1;
|
---|
354 | break;
|
---|
355 |
|
---|
356 | default:
|
---|
357 | printf("Unknown option '%c'\n", argv[i][j]);
|
---|
358 | }
|
---|
359 | }
|
---|
360 | }
|
---|
361 | else
|
---|
362 | {
|
---|
363 | res = Register(argv[i]);
|
---|
364 |
|
---|
365 | if (NS_FAILED(res))
|
---|
366 | {
|
---|
367 | ReportError(res, argv[i]);
|
---|
368 | result = -1;
|
---|
369 | }
|
---|
370 | else
|
---|
371 | {
|
---|
372 | ReportSuccess(argv[i]);
|
---|
373 | }
|
---|
374 | }
|
---|
375 | i++;
|
---|
376 | }
|
---|
377 | return result;
|
---|
378 | }
|
---|
379 |
|
---|
380 |
|
---|
381 | int main(int argc, char *argv[])
|
---|
382 | {
|
---|
383 | int ret;
|
---|
384 | nsresult rv;
|
---|
385 |
|
---|
386 | /* With no arguments, regxpcom will autoregister */
|
---|
387 | if (argc <= 1)
|
---|
388 | {
|
---|
389 | startup_xpcom();
|
---|
390 | nsCOMPtr<nsIComponentRegistrar> registrar;
|
---|
391 | rv = NS_GetComponentRegistrar(getter_AddRefs(registrar));
|
---|
392 | if (NS_FAILED(rv)) {
|
---|
393 | printf("Can not aquire component registrar\n");
|
---|
394 | return -1;
|
---|
395 | }
|
---|
396 | rv = registrar->AutoRegister(nsnull);
|
---|
397 | ret = (NS_FAILED(rv)) ? -1 : 0;
|
---|
398 | registrar = 0;
|
---|
399 | shutdown_xpcom();
|
---|
400 | } else
|
---|
401 | ret = ProcessArgs(argc, argv);
|
---|
402 |
|
---|
403 | return ret;
|
---|
404 | }
|
---|