Mercurial > trustbridge
view cinst/mozilla.c @ 173:a9e4454dee97
Implemented searching $HOME/.mozilla for profiles.ini on Linux.
author | Sascha Wilde <wilde@intevation.de> |
---|---|
date | Tue, 25 Mar 2014 16:20:04 +0100 |
parents | a46a4b443410 |
children | 6eb9149b65e1 |
line wrap: on
line source
/** * @file * @brief Mozilla installation process * * Reads from stdin a list of instructions in the form: * * I:<base64 DER econded certificate>\r\n * R:<base64 DER econded certificate>\r\n * ... * * The maximum size of an input line is 9999 characters * (including the \r\n) at the end of the line. * * Certificates marked with I: will be installed and the ones * marked with R: will be searched and if available removed from * the databases. * * This tool tries to find all NSS databases the user has * access to and to execute the instructions on all of them. * * If there are other processes accessing the databases the caller * has to ensure that those are terminated before this process is * executed. * * Returns 0 on success (Even when no stores where found) an error value * as defined in errorcodes.h otherwise. * * Success messages are written to stdout. Errors to stderr. For logging * purposes each installation / removal of a certificate will be reported * with the profile name that it modified. * */ /* @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. * */ #include <dirent.h> #include <stdbool.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/types.h> #include <debug.h> #include <errorcodes.h> #include <portpath.h> #include <strhelp.h> #ifndef _WIN32 #define LINUX 1 #else #define LINUX 0 #endif #define LINEBUFLEN 1000 /** * @brief Global Return Code * * This will be retuned by the programm and might be set to an * error code on fatal errors and to and warning code on non-fatal * errors. In case of mor than one warning the warning codes will be * ORed together. */ int return_code = 0; /** * @brief Get a list of all mozilla profile directories * * Read the profiles.ini and extract all profile paths from that. * * @param[in] inifile_name path of the profile.ini to read. * @return NULL terminated array of strings containing containing the * absolute path of the profile directories. The array needs to * be freed by the caller. */ static char ** get_profile_dirs (char *inifile_name) { char **dirs = NULL; char *inifile_dirname; FILE *inifile; char line[LINEBUFLEN]; char *key; char *value; char path[LINEBUFLEN]; char *fqpath; bool inprofile = false; bool relative_path = false; if ((inifile = fopen(inifile_name, "r")) != NULL) { inifile_dirname = port_dirname(inifile_name); while (fgets(line, LINEBUFLEN, inifile) != NULL) { /* Determine if we are in an profile section */ if (str_starts_with(line, "[Profile")) { relative_path = false; inprofile = true; } else if (line[0] == '[') inprofile = false; /* If we are in a profile parse path related stuff */ if (inprofile) { key = strtok(line, "="); value = strtok(NULL, "="); str_trim(&value); if (str_equal(key, "Path")) { if (relative_path) snprintf(path, LINEBUFLEN, "%s/%s", inifile_dirname, value); else strncpy(path, value, LINEBUFLEN); if ((fqpath = port_realpath(path)) != NULL) { strv_append(&dirs, fqpath, strlen(fqpath)); free (fqpath); } else return_code |= WARN_MOZ_PROFILE_DOES_NOT_EXIST; } else if (str_equal(key, "IsRelative") && str_starts_with(value, "1")) relative_path = true; } } } else { return_code |= WARN_MOZ_FAILED_TO_OPEN_INI; } return dirs; } /** * @brief Search for mozilla profiles.ini files * * Use well known paths and heuristics to find the current users * profiles.ini files on GNU/Linux and Windows systems. * * @return NULL terminated array of strings containing the absolute * path of the profiles.ini files. The array needs to be freed by the * caller. */ static char ** get_profile_inis () { char **inis = NULL; char path[LINEBUFLEN]; char *fqpath; DIR *mozdir; struct dirent *mozdirent; if (LINUX) { /* Search in $HOME/.mozilla */ char *home; if ((home = getenv("HOME")) == NULL) { DEBUGFPRINT("DEBUG: FATAL! No HOME in environment.\n") exit(ERR_MOZ_HOMELESS); } snprintf(path, LINEBUFLEN, "%s/%s", home, "/.mozilla"); if ((mozdir = opendir(path)) != NULL) { while ((mozdirent = readdir(mozdir)) != NULL) { if (mozdirent->d_type == DT_DIR) { snprintf(path, LINEBUFLEN, "%s/%s/%s/%s", home, "/.mozilla", mozdirent->d_name, "profiles.ini"); DEBUGFPRINT("DEBUG: checking for %s...\n", path); if ((fqpath = port_realpath(path)) != NULL) { strv_append(&inis, fqpath, strlen(fqpath)); DEBUGFPRINT("DEBUG: Found mozilla ini file: '%s'\n", fqpath); free(fqpath); } } } closedir(mozdir); } else { DEBUGFPRINT("DEBUG: Could not open %s/.mozilla\n", home) exit(WARN_MOZ_NO_PROFILES); } } else { /* Windows */ fprintf(stderr, "Windows not yet supported"); abort(); } return inis; } int main () { int x = 0; int y = 0; char **mozinis, **pdirs; if ((mozinis = get_profile_inis()) != NULL) while (mozinis[y] != NULL) { pdirs = get_profile_dirs(mozinis[y++]); if (pdirs != NULL) { while (pdirs[x] != NULL) puts(pdirs[x++]); strv_free(pdirs); } } exit(return_code); }