Fix/configurable storage paths (#55)

* when writing files, create directories if they do not exist

* revert botched merge file

* modify tasks to include debug shared lib builds

* use FILENAME_MAX from stdio instead of PATH_MAX from linux/limits

* include header guard

* Fix windows support for mkdir
This commit is contained in:
Matt Wilhelm 2019-12-05 13:10:00 -05:00 коммит произвёл Ethan Chumley
Родитель 5ebe919588
Коммит fb0fead26c
9 изменённых файлов: 160 добавлений и 3 удалений

38
.vscode/c_cpp_properties.json поставляемый
Просмотреть файл

@ -1,5 +1,16 @@
{
"configurations": [
{
"name": "Linux",
"includePath": [
"${workspaceFolder}/**"
],
"defines": [],
"compilerPath": "/usr/bin/gcc",
"cStandard": "c11",
"cppStandard": "c++17",
"intelliSenseMode": "clang-x64"
},
{
"name": "Mac",
"includePath": [
@ -8,13 +19,38 @@
"defines": [],
"macFrameworkPath": [
"/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/System/Library/Frameworks",
"/System/Library/Frameworks",
"/System/Library/Frameworks",
"/Library/Frameworks"
],
"compilerPath": "/usr/bin/clang",
"cStandard": "c11",
"cppStandard": "c++17",
"intelliSenseMode": "${default}"
},
{
"name": "Win64",
"includePath": [
"${workspaceFolder}/**",
"C:\\msys64\\mingw64\\include"
],
"defines": [
"_DEBUG",
"UNICODE",
"_UNICODE"
],
"windowsSdkVersion": "10.0.18362.0",
"compilerPath": "C:\\msys64\\mingw64\\bin\\gcc.exe",
"cStandard": "c11",
"cppStandard": "c++17",
"intelliSenseMode": "gcc-x64",
"browse": {
"path": [
"C:\\msys64\\mingw64\\include"
],
"limitSymbolsToIncludedHeaders": true,
"databaseFilename": ""
},
"forcedInclude": []
}
],
"version": 4

29
.vscode/tasks.json поставляемый
Просмотреть файл

@ -79,6 +79,35 @@
}
}
},
{
"label": "Build Shared Library (debug)",
"type": "shell",
"command": "cmake",
"group": "build",
"dependsOn": [ "CMake Build (debug)"],
"presentation": {
"echo": true,
"reveal": "always",
"focus": false,
"panel": "shared"
},
"args": ["--build", "build"],
"problemMatcher": {
"owner": "cpp",
"fileLocation": [
"relative",
"${workspaceRoot}"
],
"pattern": {
"regexp": "^(.*):(\\d+):(\\d+):\\s+(warning|error):\\s+(.*)$",
"file": 1,
"line": 2,
"column": 3,
"severity": 4,
"message": 5
}
}
},
{
"label": "Build Shared Library (release)",
"type": "shell",

Просмотреть файл

@ -63,6 +63,8 @@ add_library(electionguard
${PROJECT_SOURCE_DIR}/src/electionguard/random_source.c
${PROJECT_SOURCE_DIR}/src/electionguard/trustee_state_rep.h
${PROJECT_SOURCE_DIR}/src/electionguard/file.c
${PROJECT_SOURCE_DIR}/src/electionguard/directory.c
${PROJECT_SOURCE_DIR}/src/electionguard/directory.h
${PROJECT_SOURCE_DIR}/include/electionguard/api/config.h
${PROJECT_SOURCE_DIR}/include/electionguard/api/create_election.h
${PROJECT_SOURCE_DIR}/include/electionguard/api/encrypt_ballot.h

Просмотреть файл

@ -131,7 +131,7 @@ int main()
if (ok)
{
// Assigning an output_path fails if this folder doesn't already exist
char *output_path = "../"; // This outputs to the directy above the cwd.
char *output_path = "./ballots/"; // This outputs to the directy above the cwd.
char *output_prefix = "ballots-";
ok = API_RecordBallots(config.num_selections, current_cast_index, current_spoiled_index,
NUM_RANDOM_BALLOT_SELECTIONS, casted_ballot_ids, spoiled_ballot_ids, encrypted_ballots,
@ -162,7 +162,7 @@ int main()
uint32_t tally_results[config.num_selections];
if (ok)
{
char *output_path = "../"; // This outputs to the directy above the cwd.
char *output_path = "./tallies/"; // This outputs to the directy above the cwd.
char *output_prefix = "tally-";
ok = API_TallyVotes(config, trustee_states, DECRYPTING_TRUSTEES,
ballots_filename, output_path, output_prefix, &tally_filename, tally_results);

Просмотреть файл

@ -6,6 +6,7 @@
#include "api/filename.h"
#include "serialize/voting.h"
#include "voting/num_ballots.h"
#include "directory.h"
static bool initialize_coordinator(uint32_t num_selections);
static bool get_serialized_ballot_identifier(int64_t ballot_id, struct ballot_identifier *ballot_identifier);
@ -206,6 +207,10 @@ bool export_ballots(char *export_path, char *filename_prefix, char **output_file
printf("API_RecordBallots :: generated unique filename for export at \"%s\"\n", *output_filename);
#endif
if (ok) {
ok = create_directory(export_path);
}
if (ok)
{
FILE *out = fopen(*output_filename, "w+");

Просмотреть файл

@ -5,6 +5,7 @@
#include "api/base_hash.h"
#include "api/filename.h"
#include "directory.h"
// Initialize
static bool initialize_coordinator(void);
@ -267,6 +268,10 @@ bool export_tally_votes(char *export_path, char *filename_prefix,
printf("API_TALLYVOTES :: generated unique filename for export at \"%s\"\n", *output_filename);
#endif
if (ok) {
ok = create_directory(export_path);
}
if (ok)
{
FILE *out = fopen(*output_filename, "w+");

Просмотреть файл

@ -0,0 +1,70 @@
#include <stdio.h> /* FILENAME_MAX */
#include <sys/stat.h> /* mkdir(2) */
#include <errno.h>
#include "directory.h"
#ifndef FILENAME_MAX
#define FILENAME_MAX=256
#endif
bool create_directory(const char *path)
{
/* Adapted from http://stackoverflow.com/a/2336245/119527 */
const size_t len = strlen(path);
char _path[FILENAME_MAX];
char *p;
errno = 0;
/* Copy string so its mutable */
if (len > sizeof(_path)-1) {
errno = ENAMETOOLONG;
return false;
}
strcpy(_path, path);
char *directory_separator;
#ifdef _WIN32
directory_separator = "\\";
#else
directory_separator = "/";
#endif
/* Iterate the string */
for (p = _path + 1; *p; p++) {
if (*p == directory_separator[0]) {
/* Temporarily truncate */
*p = '\0';
int mk_dir_res = -1;
#ifdef _WIN32
mk_dir_res = mkdir(_path);
#else
mk_dir_res = mkdir(_path, S_IRWXU);
#endif
if (mk_dir_res != 0) {
if (errno != EEXIST)
return false;
}
*p = directory_separator[0];
}
}
int mk_dir_res = -1;
#ifdef _WIN32
mk_dir_res = mkdir(_path);
#else
mk_dir_res = mkdir(_path, S_IRWXU);
#endif
if (mk_dir_res != 0) {
if (errno != EEXIST)
return false;
}
return true;
}

Просмотреть файл

@ -0,0 +1,9 @@
#ifndef __DIRECTORY_H__
#define __DIRECTORY_H__
#include <stdbool.h>
#include <string.h>
bool create_directory(const char *path);
#endif /* __DIRECTORY_H__ */

Просмотреть файл

@ -182,6 +182,7 @@ Voting_Encrypter_encrypt_ballot(Voting_Encrypter encrypter,
struct Voting_Encrypter_encrypt_ballot_r balotR;
balotR.status = VOTING_ENCRYPTER_SUCCESS;
// validate selection
if (!Validate_selections(selections, encrypter->num_selections, expected_num_selected))
balotR.status = VOTING_ENCRYPTER_SELECTION_ERROR;