Mercurial > trustbridge
comparison cinst/mozilla.c @ 44:b3e8e047bc2c
Commit first scratch of mozilla installer
author | Andre Heinecke <aheinecke@intevation.de> |
---|---|
date | Fri, 14 Mar 2014 16:06:40 +0000 |
parents | |
children | bc1e6732f43c |
comparison
equal
deleted
inserted
replaced
43:5910bf9016cd | 44:b3e8e047bc2c |
---|---|
1 | |
2 #include <stdio.h> | |
3 #include <stdlib.h> | |
4 #include <sys/stat.h> | |
5 #include <unistd.h> | |
6 #include <string.h> | |
7 #include <fcntl.h> | |
8 #include <errno.h> | |
9 | |
10 /* @brief IniParser for mozilla profiles.ini | |
11 * | |
12 * Parse data to find values formed in | |
13 * | |
14 * [Profile99] | |
15 * IsRelative=1 | |
16 * Path=Profiles/fooo.bar | |
17 * | |
18 * or | |
19 * [Profile0] | |
20 * IsRelative=0 | |
21 * Path=c:\foo\bar\baz | |
22 * | |
23 * Mozilla also accepts the ini file on Windows even if it is UTF-16 | |
24 * encoded. | |
25 * */ | |
26 | |
27 | |
28 /** | |
29 * @brief Read a file into memory. | |
30 * | |
31 * @param[in] fileName Name of the file (UTF-8 encoded). | |
32 * @param[out] data Newly allocated pointer to the file content. | |
33 * @param[out] size Size in Bytes of the file content. | |
34 * @param[in] maxSize the maximum size to read. | |
35 * | |
36 * @return 0 on success an error code otherwise. | |
37 */ | |
38 | |
39 #define RAF_UNKNOWN -1 | |
40 #define RAF_UNREADABLE -2 | |
41 #define RAF_STATFAILED -3 | |
42 #define RAF_TOOLARGE -4 | |
43 #define RAF_OUTOFCORE -5 | |
44 int readFile(const char *fileName, char **data, size_t *size, | |
45 const size_t maxSize) | |
46 { | |
47 int fd = -1; | |
48 struct stat fileStat; | |
49 int rc = 0; | |
50 ssize_t bRead = 0; | |
51 int retval = -1; | |
52 | |
53 memset(&fileStat, 0, sizeof(fileStat)); | |
54 | |
55 fd = open(fileName, O_RDONLY); | |
56 if (fd == -1) { | |
57 printf("Error: %s \n", strerror(errno)); | |
58 retval = RAF_UNREADABLE; | |
59 goto cleanup; | |
60 } | |
61 | |
62 rc = fstat(fd, &fileStat); | |
63 if (rc < 0) { | |
64 printf ("Stat failed with rc: %i\n", rc); | |
65 retval = RAF_STATFAILED; | |
66 goto cleanup; | |
67 } | |
68 | |
69 // Check the size of the file | |
70 if (!fileStat.st_size) { | |
71 printf("Size zero\n"); | |
72 retval = RAF_STATFAILED; | |
73 goto cleanup; | |
74 } | |
75 | |
76 if (fileStat.st_size > maxSize && | |
77 fileStat.st_size > 0) { | |
78 printf("File too large\n"); | |
79 retval = RAF_TOOLARGE; | |
80 goto cleanup; | |
81 } | |
82 | |
83 *size = (size_t) fileStat.st_size; | |
84 | |
85 *data = (char*) malloc(*size); | |
86 | |
87 if (*data == NULL) { | |
88 retval = RAF_OUTOFCORE; | |
89 goto cleanup; | |
90 } | |
91 | |
92 bRead = read(fd, *data, *size); | |
93 | |
94 if (bRead < 0 || (size_t) bRead != *size) { | |
95 printf("Read failed\n"); | |
96 if (bRead == -1) { | |
97 printf("Error: %s \n", strerror(errno)); | |
98 } | |
99 retval = RAF_UNKNOWN; | |
100 *size = 0; | |
101 if (*data) { | |
102 free(*data); | |
103 printf("Nulling data\n"); | |
104 *data = NULL; | |
105 } | |
106 goto cleanup; | |
107 } | |
108 | |
109 cleanup: | |
110 | |
111 if (fd && fd != -1) { | |
112 close(fd); | |
113 fd = -1; | |
114 } | |
115 | |
116 return retval; | |
117 } | |
118 | |
119 | |
120 #ifndef _WIN32 | |
121 | |
122 #define INI_LOCATIONS { \ | |
123 "/.mozilla/firefox/profiles.ini", \ | |
124 "/.mozilla/thunderbird/profiles.ini", \ | |
125 NULL } | |
126 | |
127 /** | |
128 * @brief Get a list of all mozilla profile directories for this user | |
129 * | |
130 * Read the profiles.ini and extract all profile paths from that. | |
131 * | |
132 * @return NULL terminated array of strings containing containing the | |
133 * absolute path of the profile directories. The array needs to | |
134 * be freed by the caller. | |
135 */ | |
136 char **getProfilePaths() { | |
137 char *homedir = NULL, | |
138 **retval = NULL; | |
139 const char* const iniLocations[] = INI_LOCATIONS; | |
140 int i = 0; | |
141 | |
142 homedir = getenv ("HOME"); | |
143 | |
144 if (!homedir) { | |
145 printf ("Could not get HOME\n"); | |
146 return NULL; | |
147 } | |
148 | |
149 for (i = 0; iniLocations[i] != NULL; i++) { | |
150 char *candidate[MAX_PATH_LEN], | |
151 *fileContent = NULL; | |
152 const size_t needed = strnlen (homedir, MAX_PATH_LEN) + | |
153 strnlen (iniLocations[i], MAX_PATH_LEN); | |
154 fileSize = 0; | |
155 int err = 0; | |
156 | |
157 memset (candidate, 0, MAX_PATH_LEN); | |
158 | |
159 /* Verify that addition of strlen did not overflow and | |
160 * that the buffer is large enough */ | |
161 if (needed < strnlen (homedir, MAX_PATH_LEN_LEN) || needed >= MAX_PATH - 1) { | |
162 printf ("Error invalid HOME environment variable"); | |
163 return NULL; | |
164 } | |
165 | |
166 strncpy (candidate, homedir, MAX_PATH_LEN); | |
167 /* Environment might have been modified */ | |
168 if (candidate[MAX_PATH_LEN - 1] != '\0') { | |
169 printf ("Error invalid HOME"); | |
170 return NULL; | |
171 } | |
172 strncat (candidate, iniLocations[i], MAX_PATH_LEN - strnlen(candidate, | |
173 MAX_PATH_LEN) - 1); | |
174 | |
175 rc = readFile (candidate, &fileContent, &fileSize, MAX_FILESIZE); | |
176 | |
177 if (err) { | |
178 printf ("Failed to read file.\n"); | |
179 continue; | |
180 } | |
181 parseIni (fileContent, &retval); | |
182 } | |
183 } | |
184 #else /* _WIN32 */ | |
185 char **getProfilePaths() { | |
186 return NULL; | |
187 } | |
188 #endif | |
189 | |
190 int main(int argc, char *argv) { | |
191 } |