diff 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
line wrap: on
line diff
--- /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 <stdio.h>
+#include <stdlib.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <string.h>
+#include <fcntl.h>
+#include <errno.h>
+
+/* @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) {
+}

http://wald.intevation.org/projects/trustbridge/