mirror of
https://github.com/tomasriveral/NoteWrapper.git
synced 2026-08-12 10:20:46 +02:00
Add a customization option for rsync's flags
This commit is contained in:
@@ -6,3 +6,4 @@ error.log
|
|||||||
output.log
|
output.log
|
||||||
result
|
result
|
||||||
massif.out.*
|
massif.out.*
|
||||||
|
*.out.*
|
||||||
|
|||||||
@@ -67,7 +67,8 @@ Change `~/.config/notewrapper/config.json`. If it does not exist, the program sh
|
|||||||
"backup": {
|
"backup": {
|
||||||
"enable": false,
|
"enable": false,
|
||||||
"directory": "/path/to/backup",
|
"directory": "/path/to/backup",
|
||||||
"interval": "weekly"
|
"interval": "weekly",
|
||||||
|
"rsyncArgs": ["-Lqah", "--update"]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
@@ -90,7 +91,7 @@ Change `~/.config/notewrapper/config.json`. If it does not exist, the program sh
|
|||||||
`backup.directory` is the directory where the backup will go.
|
`backup.directory` is the directory where the backup will go.
|
||||||
|
|
||||||
`backup.interval` can either be `daily`, `weekly`, `monthly` or an integer. It specifies the interval between two backups.
|
`backup.interval` can either be `daily`, `weekly`, `monthly` or an integer. It specifies the interval between two backups.
|
||||||
|
`rsyncArgs` are the array of arguments that will be passed into rsync. See `man rsync` or `rsync --help`.
|
||||||
|
|
||||||
|
|
||||||
### What needs to be done (a lot)
|
### What needs to be done (a lot)
|
||||||
|
|||||||
@@ -7,5 +7,6 @@ pkgs.mkShell {
|
|||||||
pkgs.pkg-config
|
pkgs.pkg-config
|
||||||
pkgs.gdb
|
pkgs.gdb
|
||||||
pkgs.valgrind
|
pkgs.valgrind
|
||||||
|
pkgs.kdePackages.kcachegrind
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|||||||
+31
-10
@@ -1,6 +1,8 @@
|
|||||||
|
#include "cjson/cJSON.h"
|
||||||
#include "ui.h"
|
#include "ui.h"
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
#include "notes.h"
|
#include "notes.h"
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
int main(int argc, char *argv[]) {
|
int main(int argc, char *argv[]) {
|
||||||
int shouldDebug = 0;
|
int shouldDebug = 0;
|
||||||
@@ -177,12 +179,15 @@ arg_next:
|
|||||||
int doesBackup = 0;
|
int doesBackup = 0;
|
||||||
int interval = 0; // this is an int. But some times it will be inputed a string. We must translate it.
|
int interval = 0; // this is an int. But some times it will be inputed a string. We must translate it.
|
||||||
char *pathToBackup = malloc(PATH_MAX);
|
char *pathToBackup = malloc(PATH_MAX);
|
||||||
|
char **rsyncArgs = NULL;
|
||||||
|
int rsyncArgsNumber = 0;
|
||||||
cJSON *backupJSON = cJSON_GetObjectItem(json, "backup");
|
cJSON *backupJSON = cJSON_GetObjectItem(json, "backup");
|
||||||
if (backupJSON && cJSON_IsObject(backupJSON)) {
|
if (backupJSON && cJSON_IsObject(backupJSON)) {
|
||||||
cJSON *doesBackupJSON = cJSON_GetObjectItem(backupJSON, "enable");
|
cJSON *doesBackupJSON = cJSON_GetObjectItem(backupJSON, "enable");
|
||||||
if (doesBackupJSON && cJSON_IsBool(doesBackupJSON)) {
|
if (doesBackupJSON && cJSON_IsBool(doesBackupJSON)) {
|
||||||
doesBackup = cJSON_IsTrue(doesBackupJSON) ? 1 : 0;
|
doesBackup = cJSON_IsTrue(doesBackupJSON) ? 1 : 0;
|
||||||
debug("doesBackup is set to %d", doesBackup);
|
debug("doesBackup is set to %d", doesBackup);
|
||||||
|
// handles the path to the backup
|
||||||
cJSON *pathToBackupJSON = cJSON_GetObjectItem(backupJSON, "directory");
|
cJSON *pathToBackupJSON = cJSON_GetObjectItem(backupJSON, "directory");
|
||||||
if (pathToBackupJSON && cJSON_IsString(pathToBackupJSON)) {
|
if (pathToBackupJSON && cJSON_IsString(pathToBackupJSON)) {
|
||||||
char *temp = cJSON_GetStringValue(pathToBackupJSON); // we name it temp. As we can't directly set pathToBackup because snprintf doesn't like when a pointer is both an arg and the destination // temp should be freed when free(json), because cJSON_GetStringValue returns a pointer.
|
char *temp = cJSON_GetStringValue(pathToBackupJSON); // we name it temp. As we can't directly set pathToBackup because snprintf doesn't like when a pointer is both an arg and the destination // temp should be freed when free(json), because cJSON_GetStringValue returns a pointer.
|
||||||
@@ -192,30 +197,46 @@ arg_next:
|
|||||||
debug("~ was expanded to %s\nThe backup path is %s", homedir, pathToBackup);
|
debug("~ was expanded to %s\nThe backup path is %s", homedir, pathToBackup);
|
||||||
} else {
|
} else {
|
||||||
pathToBackup = strndup(temp, PATH_MAX); // temp will be freed later so strndup
|
pathToBackup = strndup(temp, PATH_MAX); // temp will be freed later so strndup
|
||||||
debug("Directory for backup is set to %s in config.json", pathToBackup);
|
debug("Directory for backup is set to %s in %s", pathToBackup, configPath);
|
||||||
}
|
}
|
||||||
} else {error(1, "user", "config.json did not contained a directory inside the backup section or the value is from an unexpected type");}
|
} else {error(1, "user", "%s did not contained a directory inside the backup section or the value is from an unexpected type", configPath);}
|
||||||
|
// handles the interval of backup
|
||||||
cJSON *intervalJSON = cJSON_GetObjectItem(backupJSON, "interval");
|
cJSON *intervalJSON = cJSON_GetObjectItem(backupJSON, "interval");
|
||||||
if (intervalJSON && cJSON_IsString(intervalJSON)) {
|
if (intervalJSON && cJSON_IsString(intervalJSON)) {
|
||||||
char *temp = cJSON_GetStringValue(intervalJSON); // se comment higher. temp will be freed when calling free(json)
|
char *temp = cJSON_GetStringValue(intervalJSON); // se comment higher. temp will be freed when calling free(json)
|
||||||
if (strcmp(temp, "daily") == 0) {
|
if (strcmp(temp, "daily") == 0) {
|
||||||
interval = DAILY;
|
interval = DAILY;
|
||||||
debug("interval in config.json is set to \"daily\" which is %d", DAILY);
|
debug("interval in %s is set to \"daily\" which is %d", configPath, DAILY);
|
||||||
} else if (strcmp(temp, "weekly") == 0) {
|
} else if (strcmp(temp, "weekly") == 0) {
|
||||||
interval = WEEKLY;
|
interval = WEEKLY;
|
||||||
debug("interval in config.json is set to \"weekly\" which is %d", WEEKLY);
|
debug("interval in %s is set to \"weekly\" which is %d", configPath, WEEKLY);
|
||||||
} else if (strcmp(temp, "monthly") == 0) {
|
} else if (strcmp(temp, "monthly") == 0) {
|
||||||
interval = MONTHLY;
|
interval = MONTHLY;
|
||||||
debug("interval in config.json is set to \"monthly\" which is %d", MONTHLY);
|
debug("interval in %s is set to \"monthly\" which is %d", configPath, MONTHLY);
|
||||||
} else {error(1, "user", "Unexpected string %s for entry \"interval\" in config.json. You must put an int (number of seconds) or \"daily\" or \"weekly\" or \"monthly\".", intervalJSON->valuestring);}
|
} else {error(1, "user", "Unexpected string %s for entry \"interval\" in %s. You must put an int (number of seconds) or \"daily\" or \"weekly\" or \"monthly\".", intervalJSON->valuestring, configPath);}
|
||||||
} else if (intervalJSON && cJSON_IsNumber(intervalJSON)) {
|
} else if (intervalJSON && cJSON_IsNumber(intervalJSON)) {
|
||||||
interval = (int)cJSON_GetNumberValue(intervalJSON);
|
interval = (int)cJSON_GetNumberValue(intervalJSON);
|
||||||
debug("interval in config.json is set to %d", interval);
|
debug("interval in %s is set to %d", configPath, interval);
|
||||||
} else {error(1, "user", "config.json did not contained an interval value inside the backup section or the value is from an unexpected type");}
|
} else {error(1, "user", "%s did not contained an interval value inside the backup section or the value is from an unexpected type", configPath);}
|
||||||
} else{error(1, "user", "config.json did not contained a enable value inside the backup section or the value is from an unexpected type");}
|
} else{error(1, "user", "%s did not contained a enable value inside the backup section or the value is from an unexpected type", configPath);}
|
||||||
|
// handle rsyncs array of arguments.
|
||||||
|
cJSON *rsyncArgsJSON = cJSON_GetObjectItem(backupJSON, "rsyncArgs");
|
||||||
|
if (rsyncArgsJSON && cJSON_IsArray(rsyncArgsJSON)) { // if it is what we expected
|
||||||
|
rsyncArgsNumber = cJSON_GetArraySize(rsyncArgsJSON);
|
||||||
|
rsyncArgs = realloc(rsyncArgs, (size_t)rsyncArgsNumber);
|
||||||
|
for (int i = 0; i < rsyncArgsNumber; i++) {
|
||||||
|
cJSON *argJSON = cJSON_GetArrayItem(rsyncArgsJSON, i);
|
||||||
|
if (argJSON && cJSON_IsString(argJSON)) {
|
||||||
|
rsyncArgs[i] = cJSON_GetStringValue(argJSON);
|
||||||
|
} else {error(1, "user", "One element in rsyncArgs array in %s is not a string", configPath);}
|
||||||
|
}
|
||||||
|
} else {error(1, "user", "%s did not contained a rsyncArgs array inside the backup section or the value is from an unexpected type", configPath);}
|
||||||
} else {
|
} else {
|
||||||
debug("In %s, \"backup\" wasn't set or we encountered a abnormal type. Defaulting to {\"enable\": false}.", configPath);
|
debug("In %s, \"backup\" wasn't set or we encountered a abnormal type. Defaulting to {\"enable\": false}.", configPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//cleans up
|
//cleans up
|
||||||
cJSON_Delete(json);
|
cJSON_Delete(json);
|
||||||
free(data);
|
free(data);
|
||||||
@@ -402,7 +423,7 @@ next_arg:
|
|||||||
debug("Finished parsing the attribute flags");
|
debug("Finished parsing the attribute flags");
|
||||||
|
|
||||||
if (doesBackup) { // (TODO LATER) when implementing multiple directories for vault we should verifiy this works.
|
if (doesBackup) { // (TODO LATER) when implementing multiple directories for vault we should verifiy this works.
|
||||||
handleBackups(notesDirectoryString, pathToBackup, homedir, interval, shouldDebug);
|
handleBackups(notesDirectoryString, pathToBackup, homedir, interval, (const char**)rsyncArgs, rsyncArgsNumber, shouldDebug);
|
||||||
}
|
}
|
||||||
|
|
||||||
initscr(); //initialize ncurses
|
initscr(); //initialize ncurses
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ input_screen:
|
|||||||
attroff(COLOR_PAIR(2));
|
attroff(COLOR_PAIR(2));
|
||||||
}
|
}
|
||||||
move(1, 1); // replace cursor
|
move(1, 1); // replace cursor
|
||||||
wgetnstr(stdscr, vaultName, sizeof(vaultName)-1);
|
wgetnstr(stdscr, vaultName, PATH_MAX-1);
|
||||||
refresh();
|
refresh();
|
||||||
endwin();
|
endwin();
|
||||||
reset_shell_mode();
|
reset_shell_mode();
|
||||||
|
|||||||
+15
-14
@@ -70,7 +70,7 @@ void _error(const int shouldDebug, const int condition, const char *type, const
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void copyDir(const char *source, const char *destination, const int shouldDebug) {
|
static void copyDir(const char *source, const char *destination, const char **rsyncArgs, const int rsyncArgsNumber, const int shouldDebug) {
|
||||||
debug("Backuping... source: %s and destination: %s", source, destination);
|
debug("Backuping... source: %s and destination: %s", source, destination);
|
||||||
pid_t pid = fork();
|
pid_t pid = fork();
|
||||||
|
|
||||||
@@ -78,16 +78,16 @@ void copyDir(const char *source, const char *destination, const int shouldDebug)
|
|||||||
|
|
||||||
if (pid == 0) {
|
if (pid == 0) {
|
||||||
// Child process: execute rsync
|
// Child process: execute rsync
|
||||||
char *args[] = { // (TODO LATER)
|
char **args = malloc((4 + rsyncArgsNumber)*sizeof(char*));
|
||||||
"rsync",
|
args[0] = "rsync";
|
||||||
"-Lqah", // archive, follow links, human-readable // (TODO LATER) add a way to get verbose (-v) without it going on top of ncurses
|
for (int i = 0; i < rsyncArgsNumber; i++) {
|
||||||
"--progress", // show progress
|
args[i+1] = (char *)rsyncArgs[i];
|
||||||
"--update", // only update if newer
|
if (i == rsyncArgsNumber-1) { // last loop
|
||||||
(char *)source,
|
args[i+2] = (char*)source;
|
||||||
(char *)destination,
|
args[i+3] = (char*)destination;
|
||||||
NULL
|
args[i+4] = NULL; // execvp expect last arg to be NULL
|
||||||
};
|
}
|
||||||
|
}
|
||||||
execvp("rsync", args);
|
execvp("rsync", args);
|
||||||
// If execvp returns, there was an error
|
// If execvp returns, there was an error
|
||||||
error(1, "program", "execvp() failed");
|
error(1, "program", "execvp() failed");
|
||||||
@@ -141,14 +141,15 @@ void initAppFilesAndDirs(const char *home, const int shouldDebug) {
|
|||||||
" \"backup\": {\n"
|
" \"backup\": {\n"
|
||||||
" \"enable\": false,\n"
|
" \"enable\": false,\n"
|
||||||
" \"directory\": \"/path/to/backup\",\n"
|
" \"directory\": \"/path/to/backup\",\n"
|
||||||
" \"interval\": \"weekly\"\n"
|
" \"interval\": \"weekly\",\n"
|
||||||
|
" \"rsyncArgs\": [\"-Lqah\", \"--update\"]\n"
|
||||||
" }\n"
|
" }\n"
|
||||||
"}\n");
|
"}\n");
|
||||||
|
|
||||||
fclose(w);
|
fclose(w);
|
||||||
}
|
}
|
||||||
|
|
||||||
void handleBackups(const char *pathOfVaults, const char *pathOfBackup, const char *homeDir, const int interval, const int shouldDebug) {
|
void handleBackups(const char *pathOfVaults, const char *pathOfBackup, const char *homeDir, const int interval, const char **rsyncArguments, const int rsyncArgumentsNumber, const int shouldDebug) {
|
||||||
int shouldBackup = 0;
|
int shouldBackup = 0;
|
||||||
time_t now = time(NULL);
|
time_t now = time(NULL);
|
||||||
debug("Time since epoch is %ld", (long)now);
|
debug("Time since epoch is %ld", (long)now);
|
||||||
@@ -194,7 +195,7 @@ void handleBackups(const char *pathOfVaults, const char *pathOfBackup, const cha
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (shouldBackup) {
|
if (shouldBackup) {
|
||||||
copyDir(pathOfVaults, pathOfBackup, shouldDebug);
|
copyDir(pathOfVaults, pathOfBackup, rsyncArguments, rsyncArgumentsNumber, shouldDebug);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+3
-2
@@ -76,6 +76,7 @@ int openEditor(char *path, char *editor, int render, int shouldJumpToEndOfFile,
|
|||||||
// you should not forgot to free this string as it is in the heap.
|
// you should not forgot to free this string as it is in the heap.
|
||||||
char *getFormatedTime(char *format, int shouldDebug);
|
char *getFormatedTime(char *format, int shouldDebug);
|
||||||
/* Caclulates if we need to do another backup (by reading ~/.cache/NoteWrapper/backupTime.txt.
|
/* Caclulates if we need to do another backup (by reading ~/.cache/NoteWrapper/backupTime.txt.
|
||||||
If need launches in the background rsync to do the backuping.*/
|
If need launches in the background rsync to do the backuping.
|
||||||
void handleBackups(const char *pathOfVaults, const char *pathOfBackup, const char *homeDir, const int interval, const int shouldDebug);
|
rsyncArgs is the array of arguments to be passed to rsync. Do not inclue destination or source. It will be added in the function.*/
|
||||||
|
void handleBackups(const char *pathOfVaults, const char *pathOfBackup, const char *homeDir, const int interval, const char **rsyncArgs, const int rsyncArgsNumber, const int shouldDebug);
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
Binary file not shown.
Reference in New Issue
Block a user