# HG changeset patch # User Andre Heinecke # Date 1394813200 0 # Node ID b3e8e047bc2c95db238d75f1d93b13a4173a40e7 # Parent 5910bf9016cd0dbb13d6af8d1db550dc0a4bdc85 Commit first scratch of mozilla installer diff -r 5910bf9016cd -r b3e8e047bc2c cinst/mozilla.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/cinst/mozilla.c Fri Mar 14 16:06:40 2014 +0000 @@ -0,0 +1,191 @@ + +#include +#include +#include +#include +#include +#include +#include + +/* @brief IniParser for mozilla profiles.ini + * + * Parse data to find values formed in + * + * [Profile99] + * IsRelative=1 + * Path=Profiles/fooo.bar + * + * or + * [Profile0] + * IsRelative=0 + * Path=c:\foo\bar\baz + * + * Mozilla also accepts the ini file on Windows even if it is UTF-16 + * encoded. + * */ + + +/** + * @brief Read a file into memory. + * + * @param[in] fileName Name of the file (UTF-8 encoded). + * @param[out] data Newly allocated pointer to the file content. + * @param[out] size Size in Bytes of the file content. + * @param[in] maxSize the maximum size to read. + * + * @return 0 on success an error code otherwise. + */ + +#define RAF_UNKNOWN -1 +#define RAF_UNREADABLE -2 +#define RAF_STATFAILED -3 +#define RAF_TOOLARGE -4 +#define RAF_OUTOFCORE -5 +int readFile(const char *fileName, char **data, size_t *size, + const size_t maxSize) +{ + int fd = -1; + struct stat fileStat; + int rc = 0; + ssize_t bRead = 0; + int retval = -1; + + memset(&fileStat, 0, sizeof(fileStat)); + + fd = open(fileName, O_RDONLY); + if (fd == -1) { + printf("Error: %s \n", strerror(errno)); + retval = RAF_UNREADABLE; + goto cleanup; + } + + rc = fstat(fd, &fileStat); + if (rc < 0) { + printf ("Stat failed with rc: %i\n", rc); + retval = RAF_STATFAILED; + goto cleanup; + } + + // Check the size of the file + if (!fileStat.st_size) { + printf("Size zero\n"); + retval = RAF_STATFAILED; + goto cleanup; + } + + if (fileStat.st_size > maxSize && + fileStat.st_size > 0) { + printf("File too large\n"); + retval = RAF_TOOLARGE; + goto cleanup; + } + + *size = (size_t) fileStat.st_size; + + *data = (char*) malloc(*size); + + if (*data == NULL) { + retval = RAF_OUTOFCORE; + goto cleanup; + } + + bRead = read(fd, *data, *size); + + if (bRead < 0 || (size_t) bRead != *size) { + printf("Read failed\n"); + if (bRead == -1) { + printf("Error: %s \n", strerror(errno)); + } + retval = RAF_UNKNOWN; + *size = 0; + if (*data) { + free(*data); + printf("Nulling data\n"); + *data = NULL; + } + goto cleanup; + } + +cleanup: + + if (fd && fd != -1) { + close(fd); + fd = -1; + } + + return retval; +} + + +#ifndef _WIN32 + +#define INI_LOCATIONS { \ + "/.mozilla/firefox/profiles.ini", \ + "/.mozilla/thunderbird/profiles.ini", \ + NULL } + +/** + * @brief Get a list of all mozilla profile directories for this user + * + * Read the profiles.ini and extract all profile paths from that. + * + * @return NULL terminated array of strings containing containing the + * absolute path of the profile directories. The array needs to + * be freed by the caller. + */ +char **getProfilePaths() { + char *homedir = NULL, + **retval = NULL; + const char* const iniLocations[] = INI_LOCATIONS; + int i = 0; + + homedir = getenv ("HOME"); + + if (!homedir) { + printf ("Could not get HOME\n"); + return NULL; + } + + for (i = 0; iniLocations[i] != NULL; i++) { + char *candidate[MAX_PATH_LEN], + *fileContent = NULL; + const size_t needed = strnlen (homedir, MAX_PATH_LEN) + + strnlen (iniLocations[i], MAX_PATH_LEN); + fileSize = 0; + int err = 0; + + memset (candidate, 0, MAX_PATH_LEN); + + /* Verify that addition of strlen did not overflow and + * that the buffer is large enough */ + if (needed < strnlen (homedir, MAX_PATH_LEN_LEN) || needed >= MAX_PATH - 1) { + printf ("Error invalid HOME environment variable"); + return NULL; + } + + strncpy (candidate, homedir, MAX_PATH_LEN); + /* Environment might have been modified */ + if (candidate[MAX_PATH_LEN - 1] != '\0') { + printf ("Error invalid HOME"); + return NULL; + } + strncat (candidate, iniLocations[i], MAX_PATH_LEN - strnlen(candidate, + MAX_PATH_LEN) - 1); + + rc = readFile (candidate, &fileContent, &fileSize, MAX_FILESIZE); + + if (err) { + printf ("Failed to read file.\n"); + continue; + } + parseIni (fileContent, &retval); + } +} +#else /* _WIN32 */ +char **getProfilePaths() { + return NULL; +} +#endif + +int main(int argc, char *argv) { +}