wilde@121: /** wilde@121: * @file wilde@121: * @brief Mozilla installation process aheinecke@99: * aheinecke@99: * Reads from stdin a list of instructions in the form: aheinecke@99: * aheinecke@99: * I:\r\n aheinecke@99: * R:\r\n aheinecke@99: * ... aheinecke@99: * aheinecke@130: * The maximum size of an input line is 9999 characters aheinecke@99: * (including the \r\n) at the end of the line. aheinecke@99: * aheinecke@99: * Certificates marked with I: will be installed and the ones aheinecke@99: * marked with R: will be searched and if available removed from aheinecke@99: * the databases. aheinecke@99: * aheinecke@99: * This tool tries to find all NSS databases the user has aheinecke@99: * access to and to execute the instructions on all of them. aheinecke@99: * aheinecke@99: * If there are other processes accessing the databases the caller aheinecke@99: * has to ensure that those are terminated before this process is aheinecke@99: * executed. aheinecke@99: * aheinecke@99: * Returns 0 on success (Even when no stores where found) an error value aheinecke@99: * as defined in errorcodes.h otherwise. aheinecke@99: * aheinecke@99: * Success messages are written to stdout. Errors to stderr. For logging aheinecke@99: * purposes each installation / removal of a certificate will be reported aheinecke@99: * with the profile name that it modified. aheinecke@99: * aheinecke@99: */ aheinecke@99: aheinecke@44: /* @brief IniParser for mozilla profiles.ini aheinecke@44: * wilde@110: * Parse data to find values formed in aheinecke@44: * aheinecke@44: * [Profile99] aheinecke@44: * IsRelative=1 aheinecke@44: * Path=Profiles/fooo.bar aheinecke@44: * aheinecke@44: * or aheinecke@44: * [Profile0] aheinecke@44: * IsRelative=0 aheinecke@44: * Path=c:\foo\bar\baz aheinecke@44: * aheinecke@44: * Mozilla also accepts the ini file on Windows even if it is UTF-16 aheinecke@44: * encoded. aheinecke@44: * */ aheinecke@44: wilde@119: #include wilde@119: #include wilde@119: #include wilde@119: #include wilde@119: wilde@113: #include wilde@147: #include wilde@119: #include wilde@113: wilde@113: #ifndef _WIN32 wilde@113: #define UNIX 1 wilde@113: #else wilde@113: #define UNIX 0 wilde@113: #endif wilde@113: wilde@147: #define LINEBUFLEN 1000 wilde@147: wilde@119: /** wilde@119: * @brief Global Return Code wilde@119: * wilde@119: * This will be retuned by the programm and might be set to an wilde@119: * error code on fatal errors and to and warning code on non-fatal wilde@119: * errors. In case of mor than one warning the warning codes will be wilde@119: * ORed together. wilde@119: */ wilde@119: int return_code = 0; aheinecke@44: aheinecke@44: /** wilde@119: * @brief Get a list of all mozilla profile directories aheinecke@44: * aheinecke@44: * Read the profiles.ini and extract all profile paths from that. aheinecke@44: * wilde@121: * @param[in] inifile_name path of the profile.ini to read. aheinecke@44: * @return NULL terminated array of strings containing containing the aheinecke@44: * absolute path of the profile directories. The array needs to aheinecke@44: * be freed by the caller. aheinecke@44: */ wilde@119: static char ** wilde@119: get_profile_dirs (char *inifile_name) wilde@119: { wilde@119: char **dirs = NULL; wilde@147: char *inifile_dirname; wilde@119: FILE *inifile; wilde@147: char line[LINEBUFLEN]; wilde@147: char *key; wilde@147: char *value; wilde@147: char path[LINEBUFLEN]; wilde@147: char *fqpath; wilde@119: bool inprofile = false; wilde@147: bool relative_path = false; aheinecke@44: wilde@119: if ((inifile = fopen(inifile_name, "r")) != NULL) wilde@119: { wilde@147: inifile_dirname = port_dirname(inifile_name); wilde@147: while (fgets(line, LINEBUFLEN, inifile) != NULL) wilde@119: { wilde@147: /* Determine if we are in an profile section */ wilde@147: if (str_starts_with(line, "[Profile")) wilde@147: { wilde@147: relative_path = false; wilde@147: inprofile = true; wilde@147: } wilde@119: else if (line[0] == '[') wilde@119: inprofile = false; wilde@147: wilde@147: /* If we are in a profile parse path related stuff */ wilde@147: if (inprofile) wilde@147: { wilde@157: key = strtok(line, "="); wilde@157: value = strtok(NULL, "="); wilde@147: str_trim(&value); wilde@147: if (str_equal(key, "Path")) wilde@147: { wilde@147: if (relative_path) wilde@147: snprintf(path, LINEBUFLEN, "%s/%s", inifile_dirname, value); wilde@147: else wilde@147: strncpy(path, value, LINEBUFLEN); wilde@147: if ((fqpath = port_realpath(path)) != NULL) wilde@147: { wilde@147: strv_append(&dirs, fqpath, strlen(fqpath)); wilde@147: free (fqpath); wilde@147: } wilde@147: else wilde@147: return_code |= WARN_MOZ_PROFILE_DOES_NOT_EXIST; wilde@147: } wilde@147: else if (str_equal(key, "IsRelative") && wilde@147: str_starts_with(value, "1")) wilde@147: relative_path = true; wilde@147: } wilde@119: } wilde@119: } wilde@119: else wilde@119: { wilde@119: return_code |= WARN_MOZ_FAILED_TO_OPEN_INI; wilde@119: } wilde@119: return dirs; wilde@119: } aheinecke@44: wilde@113: int wilde@147: main (int argc, char *argv[]) wilde@113: { wilde@119: int x = 0; wilde@147: if (argc == 2) wilde@147: { wilde@147: char **pdirs = wilde@147: get_profile_dirs(argv[1]); wilde@147: if (pdirs != NULL) wilde@147: { wilde@147: while (pdirs[x] != NULL) wilde@147: puts(pdirs[x++]); wilde@147: strv_free(pdirs); wilde@147: } wilde@147: } wilde@119: exit(return_code); aheinecke@44: }