summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorLudovic Pouzenc <ludovic@pouzenc.fr>2011-10-09 12:33:48 +0000
committerLudovic Pouzenc <ludovic@pouzenc.fr>2011-10-09 12:33:48 +0000
commit2d91cc4a3b22a1b417ca5f707f137b84262bb4ec (patch)
tree4b825dc642cb6eb9a060e54bf8d69288fbee4904 /src
parent6858221c2c09590dfe05f060f8701f874d2559ac (diff)
download2011-ddhardrescue-origin/trunk.tar.gz
2011-ddhardrescue-origin/trunk.tar.bz2
2011-ddhardrescue-origin/trunk.zip
On range tout le code actuel du trunk dans une branche nommée "0.x" et on crée une branche 1.x qui contiendra une nouvelle mouture (re-conception, méta info de packaging...).origin/trunk
git-svn-id: file:///var/svn/2011-ddhardrescue/trunk@29 d3078510-dda0-49f1-841c-895ef4b7ec81
Diffstat (limited to 'src')
-rw-r--r--src/cursesview.c291
-rw-r--r--src/ddhardrescue.c133
-rwxr-xr-xsrc/essais/compil.sh4
-rw-r--r--src/essais/test.c86
-rw-r--r--src/essais/test2.c121
-rw-r--r--src/essais/test3.c169
-rw-r--r--src/recover.c128
-rw-r--r--src/slices.c282
-rw-r--r--src/slices_evt.c29
-rw-r--r--src/utils.c27
10 files changed, 0 insertions, 1270 deletions
diff --git a/src/cursesview.c b/src/cursesview.c
deleted file mode 100644
index fcfa2d2..0000000
--- a/src/cursesview.c
+++ /dev/null
@@ -1,291 +0,0 @@
-#include "cursesview.h"
-
-#include <pthread.h>
-#include <curses.h>
-#include <panel.h>
-#include <string.h>
-
-#define CURSESWIN_COUNT 3
-
-// Global variable shared by all threads to say "finish current operation and go away"
-extern int end;
-
-// window updated by cursesUpdateSliceDump callback from "worker" thread, with a mutex for prevent fuzzy concurrent updates
-WINDOW *winUpdateSliceDump=NULL;
-static pthread_mutex_t ncursesWriteMutex = PTHREAD_MUTEX_INITIALIZER;
-address_t sliceDumpBegin, sliceDumpEnd, sliceDumpMin, sliceDumpMax;
-
-// Helpers declaration (below the interesting code of this file)
-int cursesInit(WINDOW *wins[], PANEL *panels[], int count);
-void cursesUnInit(WINDOW *wins[], PANEL *panels[], int count);
-void cursesUpdateSliceDump(slices_evt_t *slicesEvt, slice_t *modifiedSlice);
-//void printInMiddle(WINDOW *win, int starty, int startx, int width, char *string, chtype color);
-void makeWin(WINDOW **win, PANEL **panel, int h, int w, int y, int x, char title[]);
-
-void cursesMainLoop(slices_evt_t *slicesEvt) {
- char msg[255];
- int ch, i;
-
- WINDOW *wins[CURSESWIN_COUNT];
- PANEL *panels[CURSESWIN_COUNT];
-
-#ifdef NCURSES_MOUSE_VERSION
- int dispatched, res;
- int (*mouseEventListener)(MEVENT mevent, WINDOW *winDebug);
- MEVENT mevent;
- PANEL *p;
-#endif
-
- cursesInit(wins, panels, CURSESWIN_COUNT);
-
- sliceDumpBegin=sliceDumpMin=slicesEvt->data->min;
- sliceDumpEnd=sliceDumpMax=slicesEvt->data->max;
-
- wattron(wins[CURSESWIN_COUNT-1], COLOR_PAIR(4));
- mvwprintw(wins[CURSESWIN_COUNT-1], 1, 0, "F2:Exit F5:Zoom left F6:Unzoom left F7:Unzoom right F8:Zoom right");
-// wattroff(wins[CURSESWIN_COUNT-1], COLOR_PAIR(4));
-
-// update_panels();
- doupdate();
-
- /* Enable worker listener */
- //FIXME : check pointers ?
- winUpdateSliceDump=wins[1];
- slicesEvt->eventListener=cursesUpdateSliceDump;
-
- while((ch = getch()) != KEY_F(2)) {
-
- pthread_mutex_lock(&ncursesWriteMutex);
-
- switch(ch) {
- // Zoom handling
- //FIXME : Do something less stupid. Try to reuse mouse event zoom code for keyboard
- case KEY_F(5):
- sliceDumpEnd=(sliceDumpBegin+sliceDumpEnd)/2;
- break;
- case KEY_F(6):
- sliceDumpBegin=sliceDumpMin;
- break;
- case KEY_F(7):
- sliceDumpEnd=sliceDumpMax;
- break;
- case KEY_F(8):
- sliceDumpBegin=(sliceDumpBegin+sliceDumpEnd)/2;
- break;
-
- // Panel focus
- case '1':
- case '2':
- case '3':
- i=ch-'0';
- if (i>0 && i<=CURSESWIN_COUNT) {
- top_panel(panels[i-1]);
- update_panels();
- }
- break;
-#ifdef NCURSES_MOUSE_VERSION
- case KEY_MOUSE:
- // Seems to have a mouse event
- res = getmouse(&mevent);
- if ( res == OK ) {
- // Try to find in which panel (search first in top-level panel and go down)
- p=NULL;
- while ( ( p=panel_below(p) ) != NULL) {
- if ( wenclose(panel_window(p), mevent.y, mevent.x) ) {
- break;
- }
- }
-
- // If we found a panel, dispatch the event if a listener is set
- if (p != NULL) {
- mouseEventListener=(int (*)(MEVENT mevent, WINDOW *winDebug)) panel_userptr(p);
- dispatched=(mouseEventListener==NULL)?0:mouseEventListener(mevent, wins[0]);
- if ( ! dispatched ) {
- // If no listener or event not consumed, use the default behavior : set the panel on top if BUTTON1_CLICKED
- if ( (mevent.bstate & BUTTON1_CLICKED) == BUTTON1_CLICKED) {
- top_panel(p);
- }
- }
- }
- }
- break;
-#endif
- default:
- sprintf(msg, "Unhandled key ch==0x%x", ch);
- wattron(wins[0], COLOR_PAIR(4));
- mvwprintw(wins[0], 2, 0, msg);
-
- }
-
- doupdate();
-
- sprintf(msg, "Viewing [%lli-%lli] of [%lli-%lli] working region ", sliceDumpBegin, sliceDumpEnd, slicesEvt->data->min, slicesEvt->data->max);
- wattron(wins[0], COLOR_PAIR(4));
- mvwprintw(wins[0], 1, 0, msg);
-
- pthread_mutex_unlock(&ncursesWriteMutex);
- }
-
- pthread_mutex_lock(&(slicesEvt->eventListenerMutex));
- slicesEvt->eventListener=NULL;
- pthread_mutex_unlock(&(slicesEvt->eventListenerMutex));
-
- end=1;
- cursesUnInit(wins, panels, CURSESWIN_COUNT);
-}
-
-// TODO : faire une structure avec tous les éléments graphiques utiles au listener et tout passer par référence de la mainloop à ce listener
-#define DEFAULT_ZOOM_FACTOR 2.f
-
-int winSlicesMouseEventListener(MEVENT mevent, WINDOW *winDebug) {
- bool resb;
- int pX, pY, maxX, maxY;
- address_t delta;
- float pos;
- // For debugging char buf[255];
-
- pY=mevent.y;
- pX=mevent.x;
- resb=wmouse_trafo(winUpdateSliceDump, &pY, &pX, false);
- if ( resb == TRUE ) {
- getmaxyx(winUpdateSliceDump, maxY, maxX);
- // First ligne (pY) is line 1 but first char (pX) is char 0 so we have to translate Y coords by -1
- pos=(0.0f+(pY-1)*maxX+pX)/((maxY-1)*maxX-1);
- delta=sliceDumpEnd-sliceDumpBegin;
- sliceDumpBegin+=delta*pos/DEFAULT_ZOOM_FACTOR*(DEFAULT_ZOOM_FACTOR-1);
- sliceDumpEnd-=delta*(1-pos)/DEFAULT_ZOOM_FACTOR*(DEFAULT_ZOOM_FACTOR-1);
- }
-
-/*
- // Debug code
- sprintf(buf, "Debug : pX==%i, pY==%i, maxX==%i, maxY==%i, pos==%f, sliceDumpEnd==%lli, sliceDumpBegin=%lli, delta==%lli", pX, pY, maxX, maxY, pos, sliceDumpEnd, sliceDumpBegin, delta);
- wattron(winDebug, COLOR_PAIR(4));
- mvwprintw(winDebug, 2, 0, buf);
-*/
- return 1;
-}
-
-int cursesInit(WINDOW *wins[], PANEL *panels[], int count) {
- int screenH, screenW;
-#ifdef NCURSES_MOUSE_VERSION
- char buf[255];
- mmask_t mmask;
-#endif
-
- /* Initialize curses */
- initscr();
- start_color();
- raw();
- keypad(stdscr, TRUE);
- noecho();
-#ifdef NCURSES_MOUSE_VERSION
- mmask = mousemask(REPORT_MOUSE_POSITION|BUTTON1_CLICKED, NULL);
-#endif
-
- /* Initialize all the colors */
- init_pair(1, COLOR_WHITE, COLOR_BLACK);
- init_pair(2, COLOR_WHITE, COLOR_BLUE);
- init_pair(3, COLOR_BLUE, COLOR_BLACK);
- init_pair(4, COLOR_CYAN, COLOR_BLACK);
-
- /* Initialize windows and panels */
- getmaxyx(stdscr, screenH, screenW);
- if ( screenH < 8 || screenW < 40 ) return 1;
-
- makeWin(wins+0, panels+0, 3 , screenW, 0 , 0, "Menu");
- makeWin(wins+1, panels+1, screenH-6 , screenW, 3 , 0, "Main Win");
- makeWin(wins+2, panels+2, 2 , screenW, screenH-3 , 0, "Commands");
-
- /* Set up the user pointers to the next panel
- set_panel_userptr(panels[0], panels[1]);
- set_panel_userptr(panels[1], panels[2]);
- set_panel_userptr(panels[2], panels[0]);
- */
-
- set_panel_userptr(panels[1], winSlicesMouseEventListener);
-
-#ifdef NCURSES_MOUSE_VERSION
- sprintf(buf, "Debug infos : mmask=%lx", mmask);
- mvprintw(LINES - 3, 0, buf);
-#endif
-
- /* Update the stacking order. 2nd panel will be on top */
- update_panels();
-
- return 0;
-}
-
-void cursesUnInit(WINDOW *wins[], PANEL *panels[], int count) {
- int i;
-
- for (i=0;i<count;i++) {
- del_panel(panels[i]);
- delwin(wins[i]);
- }
- endwin();
-}
-
-void cursesUpdateSliceDump(slices_evt_t *slicesEvt, slice_t *modifiedSlice) {
-// char *strProgress="|/-\\";
-// static int progress=0;
- char *toPrint;
- address_t blockSize=0;
- unsigned int charCount=(getmaxx(winUpdateSliceDump)-getbegx(winUpdateSliceDump))*(getmaxy(winUpdateSliceDump)-getbegy(winUpdateSliceDump)+2);
-
- //TODO : refesh only right parts of the representation
- // This need a representation that not depends on what is already drawn because of consistency and because it not possible to re-read printed ASCII representation in curse windows
-
- pthread_mutex_lock(&ncursesWriteMutex);
-
-
- toPrint=slicesDump(slicesEvt->data, &blockSize, charCount, sliceDumpBegin, sliceDumpEnd);
- if (toPrint != NULL) {
- attron(COLOR_PAIR(4));
- mvwprintw(winUpdateSliceDump, 1, 0, toPrint);
-// attroff(COLOR_PAIR(4));
-
- update_panels();
- doupdate();
-
- free(toPrint);
- }
-
-/* sprintf(toPrint, "%c - %p %p", strProgress[progress], slicesEvt, modifiedSlice);
- progress=(progress+1)%strlen(strProgress);
-*/
- pthread_mutex_unlock(&ncursesWriteMutex);
-}
-
-/*
-void printInMiddle(WINDOW *win, int starty, int startx, int width, char *string, chtype color)
-{ int length, x, y;
- float temp;
-
- if(win == NULL)
- win = stdscr;
- getyx(win, y, x);
- if(startx != 0)
- x = startx;
- if(starty != 0)
- y = starty;
- if(width == 0)
- width = 80;
-
- length = strlen(string);
- temp = (width - length)/ 2;
- x = startx + (int)temp;
- wattron(win, color);
- mvwprintw(win, y, x, "%s", string);
- wattroff(win, color);
- refresh();
-}
-*/
-void makeWin(WINDOW **win, PANEL **panel, int h, int w, int y, int x, char title[]) {
- int i;
- *win = newwin(h, w, y, x);
- mvwprintw(*win, 0, 0, "%s", title);
- mvwchgat(*win, 0, 0, -1, A_BOLD, 2, NULL);
- for(i=1;i<h;i++) mvwchgat(*win, i, 0, -1, A_STANDOUT, 1, NULL);
- *panel = new_panel(*win);
-}
-
diff --git a/src/ddhardrescue.c b/src/ddhardrescue.c
deleted file mode 100644
index c83fffd..0000000
--- a/src/ddhardrescue.c
+++ /dev/null
@@ -1,133 +0,0 @@
-#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;
-}
-
diff --git a/src/essais/compil.sh b/src/essais/compil.sh
deleted file mode 100755
index a867c5a..0000000
--- a/src/essais/compil.sh
+++ /dev/null
@@ -1,4 +0,0 @@
-#!/bin/bash
-gcc -Wall -o ../../bin/test -g -lncurses test.c
-gcc -Wall -o ../../bin/test2 -g -lncurses -lpanel test2.c
-gcc -Wall -o ../../bin/test3 -g -lncurses -lpanel test3.c
diff --git a/src/essais/test.c b/src/essais/test.c
deleted file mode 100644
index 3a3e73f..0000000
--- a/src/essais/test.c
+++ /dev/null
@@ -1,86 +0,0 @@
-#include <ncurses.h>
-
-WINDOW *create_newwin(int height, int width, int starty, int startx)
-{ WINDOW *local_win;
-
- local_win = newwin(height, width, starty, startx);
- wborder(local_win, '|', '|', '-', '-', '+', '+', '+', '+');
-// box(local_win,0,0);
- wrefresh(local_win);
- return local_win;
-}
-
-int main() {
-
-/*
- A_NORMAL Normal display (no highlight)
- A_STANDOUT Best highlighting mode of the terminal.
- A_UNDERLINE Underlining
- A_REVERSE Reverse video
- A_BLINK Blinking
- A_DIM Half bright
- A_BOLD Extra bright or bold
- A_PROTECT Protected mode
- A_INVIS Invisible or blank mode
- A_ALTCHARSET Alternate character set
- A_CHARTEXT Bit-mask to extract a character
- COLOR_PAIR(n) Color-pair number n
-*/
- int end, ch;
- int row,col;
- char msg[256];
- WINDOW *w1;
- MEVENT event;
-
- initscr();
- getmaxyx(stdscr,row,col);
- raw();
- keypad(stdscr, TRUE);
- noecho();
-
- start_color();
- init_pair(1, COLOR_WHITE, COLOR_BLUE);
-
- mousemask(ALL_MOUSE_EVENTS, NULL);
-//http://tldp.org/HOWTO/NCURSES-Programming-HOWTO/windows.html
- //w1 = create_newwin(row/2, col/2, row/4, col/4);
- w1 = create_newwin(10, 10, 10, 10);
- attron(COLOR_PAIR(1) | A_BOLD);
- mvprintw(row-2,0,"This screen has %d rows and %d columns\n",row,col);
- attroff(COLOR_PAIR(1) | A_BOLD);
- move(0,0);
-
-
- end=0;
- while (!end) {
- refresh();
- ch=getch();
- switch(ch) {
- case KEY_MOUSE:
- if(getmouse(&event) == OK) { /* When the user clicks left mouse button */
- if(event.bstate & BUTTON1_PRESSED) {
- attrset(A_NORMAL);
- printw("mouse button1\n");
- }
- }
- break;
- case KEY_F(2):
- attrset(A_NORMAL);
- printw("F2 key\n");
- break;
- case 'q':
- end=1;
- break;
- case 'b':
- mvwchgat(w1,1,0,-1, A_REVERSE, 0, NULL);
- break;
- default:
- sprintf(msg, "%c key\n", ch);
- wattrset(w1,A_BOLD | A_UNDERLINE);
- wprintw(w1, msg);
- }
- }
- endwin();
-
- return 0;
-}
diff --git a/src/essais/test2.c b/src/essais/test2.c
deleted file mode 100644
index 3512329..0000000
--- a/src/essais/test2.c
+++ /dev/null
@@ -1,121 +0,0 @@
-
-#include <string.h>
-#include <panel.h>
-
-#define NLINES 10
-#define NCOLS 40
-
-void init_wins(WINDOW **wins, int n);
-void win_show(WINDOW *win, char *label, int label_color);
-void print_in_middle(WINDOW *win, int starty, int startx, int width, char *string, chtype color);
-
-int main()
-{ WINDOW *my_wins[3];
- PANEL *my_panels[3];
- PANEL *top;
- int ch;
-
- /* Initialize curses */
- initscr();
- start_color();
- cbreak();
- noecho();
- keypad(stdscr, TRUE);
-
- /* Initialize all the colors */
- init_pair(1, COLOR_RED, COLOR_BLACK);
- init_pair(2, COLOR_GREEN, COLOR_BLACK);
- init_pair(3, COLOR_BLUE, COLOR_BLACK);
- init_pair(4, COLOR_CYAN, COLOR_BLACK);
-
- init_wins(my_wins, 3);
-
- /* Attach a panel to each window */ /* Order is bottom up */
- my_panels[0] = new_panel(my_wins[0]); /* Push 0, order: stdscr-0 */
- my_panels[1] = new_panel(my_wins[1]); /* Push 1, order: stdscr-0-1 */
- my_panels[2] = new_panel(my_wins[2]); /* Push 2, order: stdscr-0-1-2 */
-
- /* Set up the user pointers to the next panel */
- set_panel_userptr(my_panels[0], my_panels[1]);
- set_panel_userptr(my_panels[1], my_panels[2]);
- set_panel_userptr(my_panels[2], my_panels[0]);
-
- /* Update the stacking order. 2nd panel will be on top */
- update_panels();
-
- /* Show it on the screen */
- attron(COLOR_PAIR(4));
- mvprintw(LINES - 2, 0, "Use tab to browse through the windows (F2 to Exit)");
- attroff(COLOR_PAIR(4));
- doupdate();
-
- top = my_panels[2];
- while((ch = getch()) != KEY_F(2))
- { switch(ch)
- { case 9:
- top = (PANEL *)panel_userptr(top);
- top_panel(top);
- break;
- }
- update_panels();
- doupdate();
- }
- endwin();
- return 0;
-}
-
-/* Put all the windows */
-void init_wins(WINDOW **wins, int n)
-{
- int x, y, i;
- char label[80];
-
- y = 2;
- x = 10;
- for(i = 0; i < n; ++i)
- { wins[i] = newwin(NLINES, NCOLS, y, x);
- sprintf(label, "Window Number %d", i + 1);
- win_show(wins[i], label, i + 1);
- y += 3;
- x += 7;
- }
-}
-
-/* Show the window with a border and a label */
-void win_show(WINDOW *win, char *label, int label_color)
-{ int startx, starty, height, width;
-
- getbegyx(win, starty, startx);
- getmaxyx(win, height, width);
-
- box(win, 0, 0);
- mvwaddch(win, 2, 0, ACS_LTEE);
- mvwhline(win, 2, 1, ACS_HLINE, width - 2);
- mvwaddch(win, 2, width - 1, ACS_RTEE);
-
- print_in_middle(win, 1, 0, width, label, COLOR_PAIR(label_color));
-}
-
-void print_in_middle(WINDOW *win, int starty, int startx, int width, char *string, chtype color)
-{ int length, x, y;
- float temp;
-
- if(win == NULL)
- win = stdscr;
- getyx(win, y, x);
- if(startx != 0)
- x = startx;
- if(starty != 0)
- y = starty;
- if(width == 0)
- width = 80;
-
- length = strlen(string);
- temp = (width - length)/ 2;
- x = startx + (int)temp;
- wattron(win, color);
- mvwprintw(win, y, x, "%s", string);
- wattroff(win, color);
- refresh();
-}
-
diff --git a/src/essais/test3.c b/src/essais/test3.c
deleted file mode 100644
index c763cf3..0000000
--- a/src/essais/test3.c
+++ /dev/null
@@ -1,169 +0,0 @@
-
-#include <string.h>
-#include <panel.h>
-
-#define NLINES 10
-#define NCOLS 40
-
-void init_wins(WINDOW **wins, int n);
-void win_show(WINDOW *win, char *label, int label_color);
-void print_in_middle(WINDOW *win, int starty, int startx, int width, char *string, chtype color);
-
-int main()
-{ WINDOW *my_wins[3];
- PANEL *my_panels[3];
- PANEL *top, *p, *pe;
- int ch, res;
- mmask_t mmask;
- MEVENT mevent;
- char buf[255];
-
- /* Initialize curses */
- initscr();
- start_color();
- cbreak();
- noecho();
- keypad(stdscr, TRUE);
- mmask = mousemask(REPORT_MOUSE_POSITION|BUTTON1_CLICKED, NULL);
-
- /* Initialize all the colors */
- init_pair(1, COLOR_RED, COLOR_BLACK);
- init_pair(2, COLOR_GREEN, COLOR_BLACK);
- init_pair(3, COLOR_BLUE, COLOR_BLACK);
- init_pair(4, COLOR_CYAN, COLOR_BLACK);
-
- init_wins(my_wins, 3);
-
- /* Attach a panel to each window */ /* Order is bottom up */
- my_panels[0] = new_panel(my_wins[0]); /* Push 0, order: stdscr-0 */
- my_panels[1] = new_panel(my_wins[1]); /* Push 1, order: stdscr-0-1 */
- my_panels[2] = new_panel(my_wins[2]); /* Push 2, order: stdscr-0-1-2 */
-
- /* Set up the user pointers to the next panel */
- set_panel_userptr(my_panels[0], my_panels[1]);
- set_panel_userptr(my_panels[1], my_panels[2]);
- set_panel_userptr(my_panels[2], my_panels[0]);
-
- /* Update the stacking order. 2nd panel will be on top */
- update_panels();
-
- /* Show it on the screen */
- attron(COLOR_PAIR(4));
- mvprintw(LINES - 2, 0, "Use tab to browse through the windows (F2 to Exit)");
- sprintf(buf, "Debug infos : mmask=%lx", mmask);
- mvprintw(LINES - 3, 0, buf);
- attroff(COLOR_PAIR(4));
- doupdate();
-
- top = my_panels[2];
- while((ch = getch()) != KEY_F(2))
- { switch(ch)
- { case 9: // This is tab key, but ive not found the right symbol... other that '\t'
- top = (PANEL *)panel_userptr(top);
- top_panel(top);
- break;
- case KEY_MOUSE:
- // Seems to have a mouse event
- res = getmouse(&mevent);
- if ( res == OK ) {
- // Try to find in which panel (search first in top-level panel and go down)
- pe=NULL;
- p=top;
- do {
- if ((p == NULL) || wenclose(panel_window(p), mevent.y, mevent.x) ) {
- pe = p;
- break;
- }
- p = (PANEL *)panel_userptr(top);
- } while (p != top);
-
- // If we found a panel
- if (pe != NULL) {
- // "switch" depending on event kind
- if ( (mevent.bstate & BUTTON1_CLICKED) == BUTTON1_CLICKED) {
- // A panel was clicked, set that panel on top
- top = pe;
- top_panel(top);
- // FIXME : the userptr chain of panel must reflect panel order !
- // Or may be we can crawl panels by order with ncurses method
- }
- }
-/*
- if ( (mevent.bstate & BUTTON1_CLICKED) == BUTTON1_CLICKED) {
- attron(COLOR_PAIR(4));
- sprintf(buf, "BUTTON1_CLICKED at %i/%i/%i ", mevent.x, mevent.y, mevent.z);
- mvprintw(LINES - 4, 0, buf);
- attroff(COLOR_PAIR(4));
-
- }
- */
- }
- break;
- default:
- attron(COLOR_PAIR(4));
- sprintf(buf, "Unknown key : 0x%x ", ch);
- mvprintw(LINES - 3, 0, buf);
- attroff(COLOR_PAIR(4));
- }
- update_panels();
- doupdate();
- }
- endwin();
- return 0;
-}
-
-/* Put all the windows */
-void init_wins(WINDOW **wins, int n)
-{
- int x, y, i;
- char label[80];
-
- y = 2;
- x = 10;
- for(i = 0; i < n; ++i)
- { wins[i] = newwin(NLINES, NCOLS, y, x);
- sprintf(label, "Window Number %d", i + 1);
- win_show(wins[i], label, i + 1);
- y += 3;
- x += 7;
- }
-}
-
-/* Show the window with a border and a label */
-void win_show(WINDOW *win, char *label, int label_color)
-{ int startx, starty, height, width;
-
- getbegyx(win, starty, startx);
- getmaxyx(win, height, width);
-
- box(win, 0, 0);
- mvwaddch(win, 2, 0, ACS_LTEE);
- mvwhline(win, 2, 1, ACS_HLINE, width - 2);
- mvwaddch(win, 2, width - 1, ACS_RTEE);
-
- print_in_middle(win, 1, 0, width, label, COLOR_PAIR(label_color));
-}
-
-void print_in_middle(WINDOW *win, int starty, int startx, int width, char *string, chtype color)
-{ int length, x, y;
- float temp;
-
- if(win == NULL)
- win = stdscr;
- getyx(win, y, x);
- if(startx != 0)
- x = startx;
- if(starty != 0)
- y = starty;
- if(width == 0)
- width = 80;
-
- length = strlen(string);
- temp = (width - length)/ 2;
- x = startx + (int)temp;
- wattron(win, color);
- mvwprintw(win, y, x, "%s", string);
- wattroff(win, color);
- refresh();
-}
-
diff --git a/src/recover.c b/src/recover.c
deleted file mode 100644
index 2131542..0000000
--- a/src/recover.c
+++ /dev/null
@@ -1,128 +0,0 @@
-#include "recover.h"
-
-#include <errno.h>
-#include <stdio.h>
-#include <unistd.h> /* for usleep - to be removed */
-
-// Main algorithm for recover datas
-void recover(slices_evt_t *slicesEvt, char *src, char *dst, char *ddOpts) {
- slice_t *sliceToRead;
- address_t firstError=0, median, foundMax=0;
- int res;
-
- //sliceToRead=slicesEvt->data->first;
- sliceToRead=slicesFindLargest(slicesEvt->data, S_UNKNOWN);
- while (!end) {
- // try to recover sliceToRead and split it if read error
- switch ( tryRecoverUntilError(sliceToRead, &firstError, src, dst, ddOpts) ) {
- case 0:
- // slice recovery has been executed without read error
- sliceToRead->status=S_RECOVERED;
- break;
- case EIO:
- // slice recovery has encountered a readerror
- res=sliceEvtSplit(slicesEvt, sliceToRead, firstError, S_RECOVERED, S_UNREADABLE, S_UNKNOWN);
- if (res<1) {
- //TODO
- printf("sliceEvtSplit return %d\n", res);
- exit(5);
- }
- break;
- default:
- exit(2); //TODO
- }
-
- /* Now, search the largest S_UNKNOWN zone
- split it in two parts */
- //sliceToRead=slicesFindLargest(slices, S_UNKNOWN);
- sliceToRead=slicesFindLargestFast(slicesEvt->data, &foundMax, S_UNKNOWN, foundMax, sliceToRead->next);
- if ( sliceToRead == NULL ) {
- // There is nothing more to recover, bailout
- end=1;
- continue;
- }
-
-
- median=(sliceToRead->begin+sliceToRead->end)/2;
- res=sliceEvtSplit(slicesEvt, sliceToRead, median, S_UNKNOWN, S_UNKNOWN, S_UNKNOWN);
- switch (res) {
- case 1:
- // No split, try analyse this zone
- // Should be a slice of length 1
- break;
- case 2:
- /* After splitting an S_UNKNOWN zone in two parts
- take the second for further analysis.
- We already now that this first one is just preceded by
- a read error, and errors are frequently grouped in zones,
- so trying to read a sector just after a faulty sector is
- most likely a waste of time.
- */
- sliceToRead=sliceToRead->next;
- break;
- case 3:
- // Internal error of sliceSlpit because this set of parameters prevent split by 3
- exit(6); // TODO
- break;
- case -1:
- // Memory error
- exit(5); //TODO
- break;
- default:
- // API error, all necessary cases are already listed
- exit(7); // TODO
- }
- }
-}
-
-// Method tha read source (and clone to dest) until the first read error
-int tryRecoverUntilError(slice_t *sliceToRead, address_t *firstError, char *src, char *dst, char*ddOpts) {
- //TODO : implement realy that
- //TODO : bail out hardly if WRITE error (on dest)
-
-// char ddinvocation[256];
- int res;
- address_t seek, count;
-
- seek=sliceToRead->begin;
- count=sliceToRead->end - seek + 1;
-// res=snprintf(ddinvocation, 255, "dd %s %s %s seek=%lld skip=%lld count=%lld", src, dst, ddOpts, seek, seek, count);
-//TODO : listener to put that info on the interface puts(ddinvocation);
-
-/*
- // Simulate that we have systematically a read error at first sector
- *firstError=sliceToRead->begin;
- res=EIO;
-*/
-/*
- // Simulate that we have systematically a read error at last sector
- *firstError=sliceToRead->end;
- res=EIO;
-*/
-/*
- // Simulate that we have systematically a read error at first sector
- // Simulate for each read, tha we have an error just in the middle if read for mor than one sector
- if ( sliceToRead->begin == sliceToRead->end ) {
- res=0;
- } else {
- *firstError=(sliceToRead->begin + sliceToRead->end)/2;
- res=EIO;
- }
-*/
-
- // Simulate for each read a pseudo random error position and generate some cases of full read without error
- //address_t error=sliceToRead->begin + rand()%(count);
- address_t error=sliceToRead->begin + rand()%(count/3);
- if ( error % 42 == 0 ) {
- res=0;
- } else {
- res=EIO;
- *firstError=error;
- }
-
- // Keep things humanly understandable (to be removed when real reads will be done)
- //usleep(10000);
-
- return res;
-}
-
diff --git a/src/slices.c b/src/slices.c
deleted file mode 100644
index e8f1d49..0000000
--- a/src/slices.c
+++ /dev/null
@@ -1,282 +0,0 @@
-#include "slices.h"
-
-#include <string.h>
-#include <stdio.h> /* For perror() */
-
-#define MIN(a, b) (((a) < (b)) ? (a) : (b))
-#define MAX(a, b) (((a) > (b)) ? (a) : (b))
-
-slice_t *sliceNew(address_t begin, address_t end, sliceStatus_t status, slice_t *next) {
- slice_t *s;
-
- s = malloc(1*sizeof(slice_t));
- if (s!=NULL) {
- s->begin=begin;
- s->end=end;
- s->status=status;
- s->next=next;
- }
-
- return s;
-}
-
-void sliceDelete(slice_t *s) {
- free(s);
-}
-
-// Return the numbers of slices after split (3 in the general case, 2 or 1 in particular cases. -1 is memory error)
-int sliceSplit(slices_t *slices, slice_t *initialSlice, address_t splitAt, sliceStatus_t statusBefore, sliceStatus_t statusAt, sliceStatus_t statusAfter) {
- slice_t *secondSlice, *thirdSlice, *rightSlice;
- int splitAfterSingularity, splitBeforeSingularity;
-
- /* Basically, we want to split the slice in 3 :
- [a;b] shoud be transformed in : [a;splitAt-1], [splitAt;splitAt], [splitAt+1;b]
- There is exceptions and singularities :
- * If splitAt is not within [a;b], bail out, no coherent solution
- * If splitAt==a, the first slice should not exists
- * If splitAt==b, the last slice shoud not exists
- * If a==b (and so, ==splitAt), there is nothing to split, just change status
- But, if statusBefore==statusAt, we don't want an interval [splitAt;splitAt], we want just split in 2.
- This unwanted interval should be kept merged with the first interval.
-
- For pratical reasons with pointer mess-up, the first action is to split between the second and the last slice
- and then between he first and second if needed.
- */
- pthread_mutex_lock(&(slices->writeOrConsistentReadMutex));
-
- if ( splitAt < initialSlice->begin || splitAt > initialSlice->end ) {
- pthread_mutex_unlock(&(slices->writeOrConsistentReadMutex));
- return -2;
- }
-
- // Test before act because we'll change values of the initialSlice because
- // it would become the firstSlice or even the second one if the first is zero-lenght
- splitAfterSingularity=(splitAt != initialSlice->end);
- splitBeforeSingularity=(splitAt != initialSlice->begin) && (statusBefore != statusAt);
-
- if ( splitAfterSingularity ) {
- thirdSlice = sliceNew(splitAt+1, initialSlice->end, statusAfter, initialSlice->next);
- if ( thirdSlice == NULL ) {
- pthread_mutex_unlock(&(slices->writeOrConsistentReadMutex));
- return -1;
- }
-
- initialSlice->end = splitAt;
- // No status change because we'll split again in 2 parts or not
- initialSlice->next = thirdSlice;
- if ( initialSlice == slices->last ) slices->last = thirdSlice;
- (slices->count)++;
-
- rightSlice=thirdSlice;
- } else {
- rightSlice=initialSlice->next;
- }
-
- if ( splitBeforeSingularity ) {
- secondSlice = sliceNew(splitAt, splitAt, statusAt, rightSlice);
- if ( secondSlice == NULL ) {
- pthread_mutex_unlock(&(slices->writeOrConsistentReadMutex));
- return -1;
- }
-
- initialSlice->end = splitAt-1;
- initialSlice->status=statusBefore;
- initialSlice->next = secondSlice;
- if ( initialSlice == slices->last ) slices->last = secondSlice;
- (slices->count)++;
- } else {
- initialSlice->status=statusAt; // Two cases : a==splitAt or statusAt==statusBefore
- }
-
- pthread_mutex_unlock(&(slices->writeOrConsistentReadMutex));
- return 1 + (splitBeforeSingularity?1:0) + (splitAfterSingularity?1:0);
-}
-
-void sliceDumpUpdate(char *dump, slice_t *s, address_t blockSize, unsigned int charCount, address_t begin, address_t end) {
- address_t sb,se,i;
- char ci;
-
- // If "s" slice is (partially) contained/visible in the [begin,end] display interval
- if ( !(s->end < begin) && !(s->begin > end) ) {
- // Draw the slice on the right number of characters
- // Mathematically correct, but crashes because address_t is UNSIGNED
- // sb=MAX(0, (s->begin - begin) / *blockSize);
- sb=(s->begin < begin)?0:(s->begin - begin) / blockSize;
- se=MIN((s->end - begin) / blockSize, charCount-1);
-
- /* Debug "assertion"
- if (sb >= charCount || se >= charCount) {
- printf("BUG : sb==%lli, se=%lli, charCount==%i\n", sb, se, charCount);
- printf("BUG : MAX(0, (%lli - %lli) / %lli)", s->begin, begin, blockSize);
- exit(42);
- }*/
-
- // Choose from the sent slice status the right char to draw
- switch (s->status) {
- case S_UNKNOWN: ci='_'; break;
- case S_UNREADABLE: ci='!'; break;
- case S_RECOVERED: ci='.'; break;
- default: ci='~'; break;
- }
-
- // Draw on the right number of characters, paying attention with information collision
- for (i=sb;i<=se;i++) {
- if (dump[i] == ' ' ) {
- // This is a new information
- dump[i]=ci;
- } else if ( dump[i] == ci || dump[i] == '!' ) {
- // Already the right information or error, don't modify
- } else {
- // Multiple information on the same character
- dump[i]='#';
- }
- }
- }
-}
-
-slices_t *slicesNewEmpty() {
- int res;
- slices_t *ss = malloc(1*sizeof(slices_t));
-
- if (ss==NULL) {
- return NULL;
- }
-
- memset(ss, 0, sizeof(slices_t));
- res=pthread_mutex_init(&(ss->writeOrConsistentReadMutex), NULL);
- if (res!=0) {
- free(ss);
- return NULL;
- }
-
- return ss;
-}
-
-slices_t *slicesNewSingleton(address_t begin, address_t end, sliceStatus_t status) {
- slice_t *s=NULL;
- slices_t *ss = slicesNewEmpty();
- if (ss==NULL) {
- return NULL;
- }
- s=sliceNew(begin,end,status,NULL);
- if (s==NULL) {
- free(ss);
- return NULL;
- }
- slicesAppend(ss,s);
-
- return ss;
-}
-
-void slicesDelete(slices_t *ss) {
- slice_t *curr, *toFree;
-
- curr=ss->first;
- while (curr!=NULL) {
- toFree=curr;
- curr=curr->next;
- sliceDelete(toFree);
- }
- free(ss);
-}
-
-void slicesAppend(slices_t *slices, slice_t *slice) {
- pthread_mutex_lock(&(slices->writeOrConsistentReadMutex));
-
- slice->next=NULL; //XXX Could be generalized
- if (slices->first==NULL || slices->last==NULL) {
- slices->first = slice;
- } else {
- slices->last->next=slice;
- }
- slices->last=slice;
- (slices->count)++;
-
- pthread_mutex_unlock(&(slices->writeOrConsistentReadMutex));
-}
-
-slice_t *slicesFindLargest(slices_t *slices, sliceStatus_t status) {
- slice_t *curr, *sMax = NULL;
- address_t i, iMax = 0;
-
- pthread_mutex_lock(&(slices->writeOrConsistentReadMutex));
-
- curr = slices->first;
- while (curr != NULL) {
- i=curr->end - curr->begin + 1;
- if ( curr->status == status && i > iMax ) {
- iMax = i;
- sMax = curr;
- }
- curr=curr->next;
- }
-
- pthread_mutex_unlock(&(slices->writeOrConsistentReadMutex));
- return sMax;
-}
-
-slice_t *slicesFindLargestFast(slices_t *slices, address_t *foundMax, sliceStatus_t status, address_t knownMax, slice_t *firstToTry) {
- slice_t *curr, *sMax = NULL;
- address_t i, iMax = 0;
-
-//FIXME : pthread_lock à faire avant l'appel là :-s (car argument firstToTry peut pointer vers n'importe quoi si autre thread modifie
- curr = firstToTry;
- while (curr != NULL) {
- i=curr->end - curr->begin + 1;
- if ( curr->status == status ) {
- if ( knownMax == i ) { *foundMax=i; return curr; }
- if ( i > iMax ) {
- iMax = i;
- sMax = curr;
- }
- }
- curr=curr->next;
- }
- curr = slices->first;
- while (curr != firstToTry) {
- i=curr->end - curr->begin + 1;
- if ( curr->status == status && i > iMax ) {
- iMax = i;
- sMax = curr;
- }
- curr=curr->next;
- }
- *foundMax=iMax;
- return sMax;
-}
-
-char *slicesDump(slices_t *slices, address_t *blockSize, unsigned int charCount, address_t begin, address_t end) {
- int res;
- slice_t *curr;
- char *dump;
-
- res=pthread_mutex_lock(&(slices->writeOrConsistentReadMutex));
- if (res!=0) {
- //FIXME Trashy code
- perror("slicesDump, pb lock mutex");
- exit(42);
- }
-
- // If blockSize is 0, try to autodetect to display entire slice chain
- if (*blockSize == 0) {
- *blockSize=(end-begin+1)/(charCount-1);
- // If we have a too big zoom factor, draw it at 1:1 scale
- if (*blockSize==0) *blockSize=1;
- }
-
- dump = malloc(charCount+1);
- if (dump==NULL) { return NULL; }
- memset(dump, ' ', charCount);
- dump[charCount]=0;
-
- //For each slice write in dump ASCII representation
- curr = slices->first;
- while (curr != NULL) {
- sliceDumpUpdate(dump, curr, *blockSize, charCount, begin, end);
- curr=curr->next;
- }
-
- pthread_mutex_unlock(&(slices->writeOrConsistentReadMutex));
- return dump;
-}
-
diff --git a/src/slices_evt.c b/src/slices_evt.c
deleted file mode 100644
index 4ed07c6..0000000
--- a/src/slices_evt.c
+++ /dev/null
@@ -1,29 +0,0 @@
-#include "slices_evt.h"
-
-#include <stdio.h>
-#include <pthread.h>
-
-// Event-aware version of sliceSplit (reusing it, of course)
-int sliceEvtSplit(slices_evt_t *slicesEvt, slice_t *initialSlice, address_t splitAt, sliceStatus_t statusBefore, sliceStatus_t statusAt, sliceStatus_t statusAfter) {
- int res;
- res=sliceSplit(slicesEvt->data, initialSlice, splitAt, statusBefore, statusAt, statusAfter);
-
- pthread_mutex_lock(&(slicesEvt->eventListenerMutex));
- if ( slicesEvt->eventListener != NULL ) {
- switch(res) {
- case 3:
- slicesEvt->eventListener(slicesEvt, initialSlice->next->next);
- case 2:
- slicesEvt->eventListener(slicesEvt, initialSlice->next);
- case 1:
- slicesEvt->eventListener(slicesEvt, initialSlice);
- break;
- default:
- // No events on split errors
- break;
- }
- }
- pthread_mutex_unlock(&(slicesEvt->eventListenerMutex));
- return res;
-}
-
diff --git a/src/utils.c b/src/utils.c
deleted file mode 100644
index 7305b22..0000000
--- a/src/utils.c
+++ /dev/null
@@ -1,27 +0,0 @@
-#include <stdio.h>
-#include <string.h>
-
-#include "utils.h"
-
-int parseArgs(int argc, char **argv, struct progArgs *args) {
- //TODO : implement that
- args->src="/dev/sdb";
- args->dst="./test.img";
- args->ddOpts="";
- args->beginSector=0;
- args->endSector=21474836480ULL; //10 Tio
-
- return 0;
-}
-
-void usage(char *progname) {
- printf(
-"Usage %s <src> <dst> [<beginSector> <endSector> [ddOpts]]\n\
- <src>\t\t\n\
- <dst>\t\t\n\
- <beginSector>\t\n\
- <endSector>\t\n\
- <ddOpts>\t\n\
-", progname);
-}
-