Bug 424363 - Customize Toolbar ? Restore Default Set uses gtk-refresh instead of...
[wine-gecko.git] / xulrunner / app / nsRegisterGREUnix.cpp
blob298e5da66e9867d0a087ab0ed8d5e3f00bd73d8f
1 /* ***** BEGIN LICENSE BLOCK *****
2 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
4 * The contents of this file are subject to the Mozilla Public License Version
5 * 1.1 (the "License"); you may not use this file except in compliance with
6 * the License. You may obtain a copy of the License at
7 * http://www.mozilla.org/MPL/
9 * Software distributed under the License is distributed on an "AS IS" basis,
10 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
11 * for the specific language governing rights and limitations under the
12 * License.
14 * The Original Code is Mozilla XULRunner.
16 * The Initial Developer of the Original Code is
17 * Benjamin Smedberg <benjamin@smedbergs.us>.
19 * Portions created by the Initial Developer are Copyright (C) 2005
20 * the Initial Developer. All Rights Reserved.
22 * Contributor(s):
24 * Alternatively, the contents of this file may be used under the terms of
25 * either the GNU General Public License Version 2 or later (the "GPL"), or
26 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
27 * in which case the provisions of the GPL or the LGPL are applicable instead
28 * of those above. If you wish to allow use of your version of this file only
29 * under the terms of either the GPL or the LGPL, and not to allow others to
30 * use your version of this file under the terms of the MPL, indicate your
31 * decision by deleting the provisions above and replace them with the notice
32 * and other provisions required by the GPL or the LGPL. If you do not delete
33 * the provisions above, a recipient may use your version of this file under
34 * the terms of any one of the MPL, the GPL or the LGPL.
36 * ***** END LICENSE BLOCK ***** */
38 #include "nsRegisterGRE.h"
39 #include "nsXPCOMGlue.h"
41 #include "nsXPCOM.h"
42 #include "nsIFile.h"
43 #include "nsILocalFile.h"
45 #include "nsAppRunner.h" // for MAXPATHLEN
46 #include "nsStringAPI.h"
47 #include "nsINIParser.h"
48 #include "nsCOMPtr.h"
50 #include "prio.h"
51 #include "prprf.h"
52 #include "prenv.h"
54 #include <unistd.h>
55 #include <sys/stat.h>
57 // If we can't register <buildid>.conf, we try to create a unique filename
58 // by looping through <buildid>_<int>.conf, but if something is seriously wrong
59 // we stop at 1000
60 #define UNIQ_LOOP_LIMIT 1000
62 static const char kRegFileGlobal[] = "global.reginfo";
63 static const char kRegFileUser[] = "user.reginfo";
65 class AutoFDClose
67 public:
68 AutoFDClose(PRFileDesc* fd = nsnull) : mFD(fd) { }
69 ~AutoFDClose() { if (mFD) PR_Close(mFD); }
71 PRFileDesc* operator= (PRFileDesc *fd) {
72 if (mFD) PR_Close(mFD);
73 mFD = fd;
74 return fd;
77 operator PRFileDesc* () { return mFD; }
78 PRFileDesc** operator &() { *this = nsnull; return &mFD; }
80 private:
81 PRFileDesc *mFD;
84 static PRBool
85 MakeConfFile(const char *regfile, const nsCString &greHome,
86 const GREProperty *aProperties, PRUint32 aPropertiesLen,
87 const char *aGREMilestone)
89 // If the file exists, don't create it again!
90 if (access(regfile, R_OK) == 0)
91 return PR_FALSE;
93 PRBool ok = PR_TRUE;
95 { // scope "fd" so that we can delete the file if something goes wrong
96 AutoFDClose fd = PR_Open(regfile, PR_CREATE_FILE | PR_WRONLY | PR_TRUNCATE,
97 0664);
98 if (!fd)
99 return PR_FALSE;
101 static const char kHeader[] =
102 "# Registration file generated by xulrunner. Do not edit.\n\n"
103 "[%s]\n"
104 "GRE_PATH=%s\n";
106 if (PR_fprintf(fd, kHeader, aGREMilestone, greHome.get()) <= 0)
107 ok = PR_FALSE;
109 for (PRUint32 i = 0; i < aPropertiesLen; ++i) {
110 if (PR_fprintf(fd, "%s=%s\n",
111 aProperties[i].property, aProperties[i].value) <= 0)
112 ok = PR_FALSE;
116 if (!ok)
117 PR_Delete(regfile);
119 return ok;
123 PRBool
124 RegisterXULRunner(PRBool aRegisterGlobally, nsIFile* aLocation,
125 const GREProperty *aProperties, PRUint32 aPropertiesLen,
126 const char *aGREMilestone)
128 // Register ourself in /etc/gre.d or ~/.gre.d/ and record what key we created
129 // for future unregistration.
131 nsresult rv;
133 char root[MAXPATHLEN] = "/etc/gre.d";
135 if (!aRegisterGlobally) {
136 char *home = PR_GetEnv("HOME");
137 if (!home || !*home)
138 return PR_FALSE;
140 PR_snprintf(root, MAXPATHLEN, "%s/.gre.d", home);
143 nsCString greHome;
144 rv = aLocation->GetNativePath(greHome);
145 if (NS_FAILED(rv))
146 return rv;
148 nsCOMPtr<nsIFile> savedInfoFile;
149 aLocation->Clone(getter_AddRefs(savedInfoFile));
150 nsCOMPtr<nsILocalFile> localSaved(do_QueryInterface(savedInfoFile));
151 if (!localSaved)
152 return PR_FALSE;
154 const char *infoname = aRegisterGlobally ? kRegFileGlobal : kRegFileUser;
155 localSaved->AppendNative(nsDependentCString(infoname));
157 AutoFDClose fd;
158 rv = localSaved->OpenNSPRFileDesc(PR_CREATE_FILE | PR_RDWR, 0664, &fd);
159 // XXX report error?
160 if (NS_FAILED(rv))
161 return PR_FALSE;
163 char keyName[MAXPATHLEN];
165 PRInt32 r = PR_Read(fd, keyName, MAXPATHLEN);
166 if (r < 0)
167 return PR_FALSE;
169 char regfile[MAXPATHLEN];
171 if (r > 0) {
172 keyName[r] = '\0';
174 PR_snprintf(regfile, MAXPATHLEN, "%s/%s.conf", root, keyName);
176 // There was already a .reginfo file, let's see if we are already
177 // registered.
178 if (access(regfile, R_OK) == 0) {
179 fprintf(stderr, "Warning: Configuration file '%s' already exists.\n"
180 "No action was performed.\n", regfile);
181 return PR_FALSE;
184 rv = localSaved->OpenNSPRFileDesc(PR_CREATE_FILE | PR_WRONLY | PR_TRUNCATE, 0664, &fd);
185 if (NS_FAILED(rv))
186 return PR_FALSE;
189 if (access(root, R_OK | X_OK) &&
190 mkdir(root, 0775)) {
191 fprintf(stderr, "Error: could not create '%s'.\n",
192 root);
193 return PR_FALSE;
196 PR_snprintf(regfile, MAXPATHLEN, "%s/%s.conf", root, aGREMilestone);
197 if (MakeConfFile(regfile, greHome, aProperties, aPropertiesLen,
198 aGREMilestone)) {
199 PR_fprintf(fd, "%s", aGREMilestone);
200 return PR_TRUE;
203 for (int i = 0; i < UNIQ_LOOP_LIMIT; ++i) {
204 static char buildID[30];
205 sprintf(buildID, "%s_%i", aGREMilestone, i);
207 PR_snprintf(regfile, MAXPATHLEN, "%s/%s.conf", root, buildID);
209 if (MakeConfFile(regfile, greHome, aProperties, aPropertiesLen,
210 aGREMilestone)) {
211 PR_Write(fd, buildID, strlen(buildID));
212 return PR_TRUE;
216 return PR_FALSE;
219 void
220 UnregisterXULRunner(PRBool aRegisterGlobally, nsIFile* aLocation,
221 const char *aGREMilestone)
223 nsresult rv;
225 char root[MAXPATHLEN] = "/etc/gre.d";
227 if (!aRegisterGlobally) {
228 char *home = PR_GetEnv("HOME");
229 if (!home || !*home)
230 return;
232 PR_snprintf(root, MAXPATHLEN, "%s/.gre.d", home);
235 nsCOMPtr<nsIFile> savedInfoFile;
236 aLocation->Clone(getter_AddRefs(savedInfoFile));
237 nsCOMPtr<nsILocalFile> localSaved (do_QueryInterface(savedInfoFile));
238 if (!localSaved)
239 return;
241 const char *infoname = aRegisterGlobally ? kRegFileGlobal : kRegFileUser;
242 localSaved->AppendNative(nsDependentCString(infoname));
244 PRFileDesc* fd = nsnull;
245 rv = localSaved->OpenNSPRFileDesc(PR_RDONLY, 0, &fd);
246 if (NS_FAILED(rv)) {
247 // XXX report error?
248 return;
251 char keyName[MAXPATHLEN];
252 PRInt32 r = PR_Read(fd, keyName, MAXPATHLEN);
253 PR_Close(fd);
255 localSaved->Remove(PR_FALSE);
257 if (r <= 0)
258 return;
260 keyName[r] = '\0';
262 char regFile[MAXPATHLEN];
263 PR_snprintf(regFile, MAXPATHLEN, "%s/%s.conf", root, keyName);
265 nsCOMPtr<nsILocalFile> lf;
266 rv = NS_NewNativeLocalFile(nsDependentCString(regFile), PR_FALSE,
267 getter_AddRefs(lf));
268 if (NS_FAILED(rv))
269 return;
271 nsINIParser p;
272 rv = p.Init(lf);
273 if (NS_FAILED(rv))
274 return;
276 rv = p.GetString(aGREMilestone, "GRE_PATH", root, MAXPATHLEN);
277 if (NS_FAILED(rv))
278 return;
280 rv = NS_NewNativeLocalFile(nsDependentCString(root), PR_TRUE,
281 getter_AddRefs(lf));
282 if (NS_FAILED(rv))
283 return;
285 PRBool eq;
286 if (NS_SUCCEEDED(aLocation->Equals(lf, &eq)) && eq)
287 PR_Delete(regFile);