Back to index

lightning-sunbird  0.9+nobinonly
regxpcom.cpp
Go to the documentation of this file.
00001 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
00002 /* ***** BEGIN LICENSE BLOCK *****
00003  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
00004  *
00005  * The contents of this file are subject to the Mozilla Public License Version
00006  * 1.1 (the "License"); you may not use this file except in compliance with
00007  * the License. You may obtain a copy of the License at
00008  * http://www.mozilla.org/MPL/
00009  *
00010  * Software distributed under the License is distributed on an "AS IS" basis,
00011  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
00012  * for the specific language governing rights and limitations under the
00013  * License.
00014  *
00015  * The Original Code is mozilla.org code.
00016  *
00017  * The Initial Developer of the Original Code is
00018  * Netscape Communications Corporation.
00019  * Portions created by the Initial Developer are Copyright (C) 1998
00020  * the Initial Developer. All Rights Reserved.
00021  *
00022  * Contributor(s):
00023  *   Pierre Phaneuf <pp@ludusdesign.com>
00024  *   Mike Shaver <shaver@mozilla.org>
00025  *
00026  * Alternatively, the contents of this file may be used under the terms of
00027  * either of the GNU General Public License Version 2 or later (the "GPL"),
00028  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
00029  * in which case the provisions of the GPL or the LGPL are applicable instead
00030  * of those above. If you wish to allow use of your version of this file only
00031  * under the terms of either the GPL or the LGPL, and not to allow others to
00032  * use your version of this file under the terms of the MPL, indicate your
00033  * decision by deleting the provisions above and replace them with the notice
00034  * and other provisions required by the GPL or the LGPL. If you do not delete
00035  * the provisions above, a recipient may use your version of this file under
00036  * the terms of any one of the MPL, the GPL or the LGPL.
00037  *
00038  * ***** END LICENSE BLOCK ***** */
00039 
00040 #include "stdlib.h"
00041 #include "prenv.h"
00042 #include "nspr.h"
00043 
00044 #include "nsXPCOMPrivate.h" // for XPCOM_DLL defines.
00045 
00046 #include "nsXPCOMGlue.h"
00047 #include "nsIComponentManager.h"
00048 #include "nsIComponentRegistrar.h"
00049 #include "nsIServiceManager.h"
00050 #include "nsCOMPtr.h"
00051 #include "nsILocalFile.h"
00052 #include "nsEmbedString.h"
00053 #include "nsIDirectoryService.h"
00054 #include "nsDirectoryServiceDefs.h"
00055 
00056 
00057 static PRBool gUnreg = PR_FALSE, gQuiet = PR_FALSE;
00058 
00059 static const char* gXPCOMLocation = nsnull;
00060 static const char* gCompRegLocation = nsnull;
00061 static const char* gXPTIDatLocation = nsnull;
00062 
00063 class DirectoryServiceProvider : public nsIDirectoryServiceProvider
00064 {
00065   public:
00066   DirectoryServiceProvider() {}
00067   
00068   NS_DECL_ISUPPORTS
00069   NS_DECL_NSIDIRECTORYSERVICEPROVIDER
00070 
00071   private:
00072   ~DirectoryServiceProvider() {}
00073 };
00074 
00075 NS_IMPL_ISUPPORTS1(DirectoryServiceProvider, nsIDirectoryServiceProvider)
00076 
00077 NS_IMETHODIMP
00078 DirectoryServiceProvider::GetFile(const char *prop, PRBool *persistant, nsIFile **_retval)
00079 {    
00080   nsCOMPtr<nsILocalFile> localFile;
00081   nsresult rv = NS_ERROR_FAILURE;
00082 
00083   *_retval = nsnull;
00084   *persistant = PR_TRUE;
00085 
00086   const char* fileLocation = nsnull;
00087 
00088   if(strcmp(prop, NS_XPCOM_CURRENT_PROCESS_DIR) == 0 && gXPCOMLocation)
00089   {
00090     fileLocation = gXPCOMLocation;
00091   }
00092   else if(strcmp(prop, NS_XPCOM_COMPONENT_REGISTRY_FILE) == 0 && gCompRegLocation)
00093   {
00094     fileLocation = gCompRegLocation;
00095   }    
00096   else if(strcmp(prop, NS_XPCOM_XPTI_REGISTRY_FILE) == 0 && gXPTIDatLocation)
00097   {
00098     fileLocation = gXPTIDatLocation;
00099   }
00100   else
00101     return NS_ERROR_FAILURE;
00102 
00103   rv = NS_NewNativeLocalFile(nsEmbedCString(fileLocation), PR_TRUE, getter_AddRefs(localFile));  
00104   if (NS_FAILED(rv)) return rv;
00105 
00106   return localFile->QueryInterface(NS_GET_IID(nsIFile), (void**)_retval);
00107 }
00108 
00109 int startup_xpcom()
00110 {
00111   nsresult rv;
00112 
00113   if (gXPCOMLocation) {
00114     int len = strlen(gXPCOMLocation);
00115     char* xpcomPath = (char*) malloc(len + sizeof(XPCOM_DLL) + sizeof(XPCOM_FILE_PATH_SEPARATOR) + 1);
00116     sprintf(xpcomPath, "%s" XPCOM_FILE_PATH_SEPARATOR XPCOM_DLL, gXPCOMLocation);
00117 
00118     rv = XPCOMGlueStartup(xpcomPath);
00119 
00120     free(xpcomPath);
00121 
00122     const char* path = getenv(XPCOM_SEARCH_KEY);
00123     if (!path) {
00124       path = "";
00125     }
00126   }
00127   else 
00128   {
00129     rv = XPCOMGlueStartup(nsnull);
00130   }
00131 
00132   if (NS_FAILED(rv)) 
00133   {
00134     printf("Can not initialize XPCOM Glue\n");
00135     return -1;
00136   }
00137 
00138   DirectoryServiceProvider *provider = new DirectoryServiceProvider();
00139   if ( !provider )
00140   {
00141     NS_WARNING("GRE_Startup failed");
00142     XPCOMGlueShutdown();
00143     return -1;
00144   }
00145 
00146   nsCOMPtr<nsILocalFile> file;
00147   if (gXPCOMLocation) 
00148   {
00149     rv = NS_NewNativeLocalFile(nsEmbedCString(gXPCOMLocation), 
00150                                PR_TRUE, 
00151                                getter_AddRefs(file));
00152   }
00153 
00154   NS_ADDREF(provider);
00155   rv = NS_InitXPCOM2(nsnull, file, provider);
00156   NS_RELEASE(provider);
00157     
00158   if (NS_FAILED(rv)) {
00159     printf("Can not initialize XPCOM\n");
00160     XPCOMGlueShutdown();
00161     return -1;
00162   }
00163 
00164   return 0;
00165 }
00166 
00167 void shutdown_xpcom()
00168 {
00169   nsresult rv;
00170 
00171   rv = NS_ShutdownXPCOM(nsnull);
00172 
00173   if (NS_FAILED(rv)) {
00174     printf("Can not shutdown XPCOM cleanly\n");
00175   }
00176 
00177   rv = XPCOMGlueShutdown();
00178   
00179   if (NS_FAILED(rv)) {
00180     printf("Can not shutdown XPCOM Glue cleanly\n");
00181   }
00182 }
00183 
00184 
00185 nsresult Register(const char *path) 
00186 { 
00187   startup_xpcom();
00188 
00189   nsresult rv;
00190   nsCOMPtr<nsILocalFile> spec;
00191   
00192   if (path) {
00193     rv = NS_NewNativeLocalFile(nsEmbedCString(path), 
00194                                PR_TRUE, 
00195                                getter_AddRefs(spec));
00196   }
00197 
00198   nsCOMPtr<nsIComponentRegistrar> registrar;
00199   rv = NS_GetComponentRegistrar(getter_AddRefs(registrar));
00200   if (NS_FAILED(rv)) {
00201     printf("Can not aquire component registrar\n");
00202     return rv;
00203   }
00204 
00205   if (gUnreg)
00206     rv = registrar->AutoUnregister(spec);
00207   else
00208     rv = registrar->AutoRegister(spec);
00209 
00210   spec = 0;
00211   registrar = 0;
00212 
00213   shutdown_xpcom();
00214   return rv;
00215 }
00216 
00217 
00218 void ReportSuccess(const char *file)
00219 {
00220   if (gQuiet)
00221     return;
00222 
00223   if (gUnreg)
00224     printf("Unregistration successful for %s\n", file);
00225   else
00226     printf("Registration successful for %s\n", file);
00227 }
00228 
00229 void ReportError(nsresult err, const char *file)
00230 {
00231   if (gUnreg)
00232     printf("Unregistration failed: (");
00233   else
00234     printf("Registration failed: (");
00235   
00236   switch (err) 
00237   {
00238     case NS_ERROR_FACTORY_NOT_LOADED:
00239       printf("Factory not loaded");
00240       break;
00241     case NS_NOINTERFACE:
00242       printf("No Interface");
00243       break;
00244     case NS_ERROR_NULL_POINTER:
00245       printf("Null pointer");
00246       break;
00247     case NS_ERROR_OUT_OF_MEMORY:
00248       printf("Out of memory");
00249       break;
00250     default:
00251       printf("%x", (unsigned)err);
00252   }
00253   
00254   printf(") %s\n", file);
00255 }
00256 
00257 void printHelp()
00258 {
00259   printf(
00260 "Mozilla regxpcom - a registration tool for xpcom components                    \n"
00261 "                                                                               \n"
00262 "Usage: regxpcom [options] [file-or-directory]                                  \n"
00263 "                                                                               \n"
00264 "Options:                                                                       \n"
00265 "         -x path        Specifies the location of a directory containing the   \n"
00266 "                        xpcom library which will be used when registering new  \n"
00267 "                        component libraries.  This path will also be added to  \n"
00268 "                        the \"load library\" path.  If not specified, the      \n"
00269 "                        current working directory will be used.                \n"
00270 "         -c path        Specifies the location of the compreg.dat file.  If    \n"
00271 "                        not specifed, the compreg.dat file will be in its      \n"
00272 "                        default location.                                      \n"
00273 "         -d path        Specifies the location of the xpti.dat file.  If not   \n"
00274 "                        specifed, the xpti.dat file will be in its default     \n"
00275 "                        location.                                              \n"
00276 "         -a             Option to register all files in the default component  \n"
00277 "                        directories.  This is the default behavior if regxpcom \n"
00278 "                        is called without any arguments.                       \n"
00279 "         -h             Displays this help screen.  Must be the only option    \n"
00280 "                        specified.                                             \n"
00281 "         -u             Option to uninstall the files-or-directory instead of  \n"
00282 "                        registering them.                                      \n"
00283 "         -q             Quiets some of the output of regxpcom.                 \n\n");
00284 }
00285 
00286 int ProcessArgs(int argc, char *argv[])
00287 {
00288   int i = 1, result = 0;
00289   nsresult res;
00290 
00291   while (i < argc) 
00292   {
00293     if (argv[i][0] == '-') 
00294     {
00295       int j;
00296       for (j = 1; argv[i][j] != '\0'; j++) 
00297       {
00298         switch (argv[i][j]) 
00299         {
00300           case 'h':
00301             printHelp();
00302             return 0;  // we are all done!
00303 
00304           case 'u':
00305             gUnreg = PR_TRUE;
00306             break;
00307 
00308           case 'q':
00309             gQuiet = PR_TRUE;
00310             break;
00311 
00312           case 'a':
00313           {
00314             res = Register(nsnull);
00315             if (NS_FAILED(res)) 
00316             {
00317               ReportError(res, "component directory");
00318               result = -1;
00319             } 
00320             else 
00321             {
00322               ReportSuccess("component directory");
00323             }
00324           }
00325           break;
00326 
00327           case 'x':
00328             gXPCOMLocation = argv[++i];
00329             j = strlen(gXPCOMLocation) - 1;
00330             break;
00331 
00332           case 'c':
00333             gCompRegLocation = argv[++i];
00334             j = strlen(gCompRegLocation) - 1;
00335             break;
00336 
00337           case 'd':
00338             gXPTIDatLocation = argv[++i];
00339             j = strlen(gXPTIDatLocation) - 1;
00340             break;
00341 
00342           default:
00343             printf("Unknown option '%c'\n", argv[i][j]);
00344         }
00345       }
00346     } 
00347     else
00348     {
00349       res = Register(argv[i]);
00350       
00351       if (NS_FAILED(res)) 
00352       {
00353         ReportError(res, argv[i]);
00354         result = -1;
00355       } 
00356       else 
00357       {
00358         ReportSuccess(argv[i]);
00359       }
00360     }
00361     i++;
00362   }
00363   return result;
00364 }
00365 
00366 
00367 int main(int argc, char *argv[])
00368 {
00369   int ret;
00370   nsresult rv;
00371 
00372   /* With no arguments, regxpcom will autoregister */
00373   if (argc <= 1)
00374   {
00375     startup_xpcom();
00376     nsCOMPtr<nsIComponentRegistrar> registrar;
00377     rv = NS_GetComponentRegistrar(getter_AddRefs(registrar));
00378     if (NS_FAILED(rv)) {
00379       printf("Can not aquire component registrar\n");
00380       return -1;
00381     }
00382     rv = registrar->AutoRegister(nsnull);
00383     ret = (NS_FAILED(rv)) ? -1 : 0;
00384     registrar = 0;
00385     shutdown_xpcom();
00386   } else
00387     ret = ProcessArgs(argc, argv);
00388 
00389   return ret;
00390 }