summaryrefslogtreecommitdiff
path: root/src/ddhardrescue.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/ddhardrescue.c')
-rw-r--r--src/ddhardrescue.c133
1 files changed, 133 insertions, 0 deletions
diff --git a/src/ddhardrescue.c b/src/ddhardrescue.c
new file mode 100644
index 0000000..c83fffd
--- /dev/null
+++ b/src/ddhardrescue.c
@@ -0,0 +1,133 @@
+#include <signal.h>
+#include <pthread.h>
+#include <string.h> /* For memset() */
+
+#include "slices_evt.h"
+#include "utils.h"
+#include "recover.h"
+#include "cursesview.h"
+
+// Global variable shared by all threads to say "finish current operation and go away"
+int end=0;
+
+void sigHookAbrt() {
+ end=1;
+}
+
+// Main thread procedures declaration and a struct for passing arguments in a clean way
+void *procWorker(void *a);
+void *procViewer(void *a);
+
+struct threadArgs {
+ struct progArgs *progArgs;
+ slices_evt_t *slices;
+};
+
+int main(int argc, char **argv) {
+ // System structures
+ struct sigaction sa;
+ pthread_t tWorker;
+
+ // Main data structure
+ slices_evt_t slices;
+
+ // Progam and threads arguments
+ struct progArgs args;
+ struct threadArgs tArgs;
+
+ // Algorithmic needs
+ int res;
+
+ // Parse command-line arguments
+ res=parseArgs(argc, argv, &args);
+ if (res!=0) {
+ usage(argv[0]);
+ return 1;
+ }
+
+ // Set signals behavior
+ memset(&sa,0,sizeof(sa));
+ sa.sa_handler=sigHookAbrt;
+ res=sigaction(SIGABRT, &sa, NULL);
+ if (res!=0) {
+ return 2;
+ }
+
+ //XXX Remove srand : only for simulation
+ srand(4);
+
+ // Initialize main data structure
+ //XXX provide a method to do that ?
+ memset(&slices, 0, sizeof(slices));
+ slices.data=slicesNewSingleton(args.beginSector, args.endSector, S_UNKNOWN);
+ if ( slices.data == NULL ) {
+ return 3;
+ }
+ slices.data->min=args.beginSector;
+ slices.data->max=args.endSector;
+ res=pthread_mutex_init(&(slices.eventListenerMutex), NULL);
+ if (res!=0) {
+ return 4;
+ }
+
+ // Threads preparation, creation and start
+ memset(&tArgs, 0, sizeof(tArgs));
+ tArgs.progArgs=&args;
+ tArgs.slices=&slices;
+
+
+ res=pthread_create(&tWorker, NULL, procWorker, &tArgs);
+ if (res!=0) {
+ return 5;
+ }
+
+ // Ncurses interface run in the main thread
+ (void) procViewer((void*)&tArgs);
+
+ // Thread join point (wait worker thread when viewer is done)
+ (void) pthread_join(tWorker, NULL);
+
+ //Final dump of datas
+ address_t blockSize=0;
+ char *dump;
+ dump=slicesDump(slices.data, &blockSize, 10000, args.beginSector, args.endSector);
+ if (dump != NULL) {
+ puts(dump);
+ free(dump);
+ }
+ printf("blockSize==%lld\n", blockSize);
+ printf("slices->count==%d\n", slices.data->count);
+
+
+ //Resources desallocation
+ (void) pthread_mutex_destroy(&(slices.eventListenerMutex));
+ slicesDelete(slices.data);
+
+ return 0;
+}
+
+void *procWorker(void *a) {
+ struct threadArgs *tArgs = (struct threadArgs *)a;
+
+ //XXX : We will need something more controlable than just a blocking call to the main algorithm
+ recover(
+ tArgs->slices,
+ tArgs->progArgs->src,
+ tArgs->progArgs->dst,
+ tArgs->progArgs->ddOpts
+ );
+
+ return a;
+}
+
+
+void *procViewer(void *a) {
+ struct threadArgs *tArgs = (struct threadArgs *)a;
+
+ cursesMainLoop(
+ tArgs->slices
+ );
+
+ return a;
+}
+