Mercurial > trustbridge
view cinst/mozilla.c @ 64:fb9f78f7ab2f
Improve error handling free memory before exiting. Include line endings in Marker lines
author | Andre Heinecke <aheinecke@intevation.de> |
---|---|
date | Tue, 18 Mar 2014 14:14:15 +0000 |
parents | b3e8e047bc2c |
children | bc1e6732f43c |
line wrap: on
line source
#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) { }