📄 devcfgcommands.c
字号:
#include "all.h"#define SECTOR_SIZE 512#define READ_TRIES 3#define WRITE_TRIES 3#include <stdio.h>#include <readline/readline.h>#include <readline/history.h>#include <stdlib.h>#include "shell.h"#include "cryptodevcfg.h"#include <sys/types.h> /* opendir, readdir */#include <dirent.h> /* opendir, readdir */#include <fcntl.h>#include "globalvars.h"/* FIXME: TODO: 'setup' command for attaching loop to device? * if implementing setup, then another * field in 'list' - attached - would be needed */ voidprintDeviceLine(index, node) int index; xmlNodePtr node;{ xmlChar* dst; xmlChar* src; xmlChar* driver; xmlChar* action; dst = xmlGetProp(node, "dst"); src = xmlGetProp(node, "src"); action = xmlGetProp(node, "action"); driver = (xmlChar*) node->name; printf(" %2d\r", index); printf(" \t%s\r", dst); printf(" \t\t\t\t%s\r", src); printf(" \t\t\t\t\t\t%s\r", driver); if (NULL != action) printf(" \t\t\t\t\t\t\t\t%s\n", action); else printf("\n"); xmlFree(dst); xmlFree(src); xmlFree(action); return;}intcList(arg) char* arg;{ xmlNodePtr* dtab; int i; fillDeviceTab(&dtab); if (NULL == dtab[0]) printf("No devices defined in configuration file.\n"); else { printf(" #\r"); printf(" \tTarget device\r"); printf(" \t\t\t\tSource device\r"); printf(" \t\t\t\t\t\tDriver\r"); printf(" \t\t\t\t\t\t\t\tAction\n"); for (i = 0; NULL != dtab[i]; i++) { printDeviceLine(i, dtab[i]); } } free(dtab); return 1;}intfindFreeLoop(out_loop) char** out_loop;{ char* loop; DIR* dir; struct dirent* ent; char* dev; int fd, ret; struct loop_info64 li; char* fullname; dir = opendir("/dev/"); if (NULL == dir) return -1; /* Scan dev directory */ loop = (char*) NULL; while( NULL != (ent = readdir(dir))) { dev = ent->d_name; /* For every loop device found check if it is unused */ if (0 == strncmp(dev, "loop", 4)) { xstrcat(&fullname, "/dev/", dev); fd = open(fullname, O_RDWR); if (-1 != fd) { ret = ioctl(fd, LOOP_GET_STATUS, &li); if (-1 == ret) { /* Found unused loop device */ loop = strdup(fullname); } close(fd); } free(fullname); if (NULL != loop) break; } } closedir(dir); if (NULL == loop) return -1; *out_loop = loop; return 1;}intgetBlocksNum(out_numblocks, dev) unsigned long* out_numblocks; char* dev;{ int fd, ret; unsigned long numblocks; fd = open(dev, O_RDONLY); if (-1 == fd) return -1; ret = ioctl(fd, BLKGETSIZE, &numblocks); close(fd); if (-1 != ret) *out_numblocks = numblocks; return ret;}intreadBlock(src, buf, i, out_error) int src; char* buf; unsigned long i; char** out_error;{ int result; int readTriesLeft; off_t oret; int br; readTriesLeft = READ_TRIES; result = 0; while (readTriesLeft > 0) { /* Position file pointer in correct place */ oret = lseek(src, i * ((off_t) SECTOR_SIZE), SEEK_SET); if (-1 == oret) { /* Seek failed - fatal error - abort */ *out_error = strerror(errno); result = -1; break; } /* Read data from src to buffer */ br = read(src, buf, SECTOR_SIZE); readTriesLeft--; if (SECTOR_SIZE == br) { /* Read full sector - ok */ *out_error = "Ok"; result = 1; break; } else if (-1 == br) { /* Check errno */ if (EIO == errno) { /* I/O error - probably bad block - continue */ *out_error = strerror(errno); result = 0; break; } else if (EINTR == errno) { /* Read interrupted by signal - no data read. * Need to repeat read of this block */ *out_error = strerror(errno); result = 0; continue; } else { /* Unknown error - abort */ *out_error = strerror(errno); result = -1; break; } } else if (br == 0) { /* End of file */ *out_error = "Premature end of file"; result = -1; break; } else { /* Read too few data - repeat read */ *out_error = "Too small data block read"; result = 0; continue; } } return result;}intwriteBlock(dst, buf, i, out_error) int dst; char* buf; unsigned long i; char** out_error;{ int result; int writeTriesLeft; off_t oret; int bw; writeTriesLeft = WRITE_TRIES; result = 0; while (writeTriesLeft > 0) { /* Position file pointer in correct place */ oret = lseek(dst, i * ((off_t) SECTOR_SIZE), SEEK_SET); if (-1 == oret) { /* Seek failed - fatal error - abort */ *out_error = strerror(errno); result = -1; break; } /* Write data from buffer to dst */ bw = write(dst, buf, SECTOR_SIZE); writeTriesLeft--; if (SECTOR_SIZE == bw) { /* Full sector written - ok */ *out_error = "Ok"; result = 1; break; } else if (-1 == bw) { /* Check errno */ if (EIO == errno) { /* I/O error - probably bad block - continue */ *out_error = strerror(errno); result = 0; break; } else if (EINTR == errno) { /* Write interrupted by signal - no data was written. * Need to repeat write of this block */ *out_error = strerror(errno); result = 0; continue; } else { /* Unknown error - abort */ *out_error = strerror(errno); result = -1; break; } } else if (bw == 0) { /* Empty write */ *out_error = "Nothing was written"; result = -1; break; } else { /* Written too few data - repeat write */ *out_error = "Too small data block written"; result = 0; continue; } } return result;}/* FIXME: add "CTRL-C stops encryption/decryption" feature */intddProgress(srcName, dstName, numblocks) char* srcName; char* dstName; unsigned long numblocks;{ int src, dst; u_int8_t buf[SECTOR_SIZE]; unsigned long i; int result, ret, updateProgress; char* errorString; unsigned long step; step = numblocks/100; if (step > 1024) step = 1024; result = -1; src = open(srcName, O_RDONLY); if (-1 != src) { dst = open(dstName, O_WRONLY); if (-1 == dst) close(src); else { updateProgress = 1; for (i = 0;; i++) { if ((0 == (i % step)) || (i == (numblocks - 1)) || (1 == updateProgress)) fprintf(stderr, "\r%lu/%lu [%lu%%]", i + 1, numblocks, (i * 100) / (numblocks - 1)); updateProgress = 0; if (i >= numblocks) { fprintf(stderr, "\n"); result = 1; break; } ret = readBlock(src, buf, i, &errorString); if (-1 == ret) { /* Fatal read error - abort */ fprintf(stderr, "\nFatal error reading sector %lu: %s\n", i + 1, errorString); break; } else if (0 == ret) { /* Non fatal read error - do not write this block */ fprintf(stderr, "\nError reading sector %lu: %s\n", i + 1, errorString); updateProgress = 1; continue; } ret = writeBlock(dst, buf, i, &errorString); if (-1 == ret) { /* Fatal write error - abort */ fprintf(stderr, "\nFatal error writing sector %lu: %s\n", i + 1, errorString); break; } else if (0 == ret) { /* Non fatal write error */ fprintf(stderr, "\nError writing sector %lu: %s\n", i + 1, errorString); updateProgress = 1; continue; } } close(dst); } close(src); } return result;}voidperformCryptoAction(device) xmlNodePtr device;{ int ret; char* loop; xmlChar* driver; xmlChar* src; char* out_error; u_int8_t* mk; xmlChar* emkt; xmlChar* action; unsigned long numblocks; driver = (xmlChar*) device->name; /* Get src device */ src = xmlGetProp(device, "src"); printf("%s: ", src); if (0 == xmlStrcmp(driver, "loopaes")) { ret = findFreeLoop(&loop); if (-1 == ret) printf("No free /dev/loop devices found.\n"); else { /* Get key */ emkt = xmlNodeListGetString(ctab, device->xmlChildrenNode, 1); ret = loopaesGetMultiKey(&mk, device); xmlFree(emkt); if (-1 == ret) { printf("Error: Could not get multikey.\n"); } else { /* Setup device using temporary loop */ ret = loopaesSetupDevice(mk, src, loop, &out_error); if (-1 == ret) { printf("Error setting device: %s.\n", out_error); } else { /* Perform crypto operation depending on action */ action = xmlGetProp(device, "action"); if (NULL == action) { printf("No action requested for this device."); } else { if (0 == xmlStrcmp(action, "encrypt")) { printf("Performing encryption using '%s' as temporary loop device...\n", loop); ret = getBlocksNum(&numblocks, loop); if (-1 == ret) { printf("Could not get device size.\n"); } else { ret = ddProgress(src, loop, numblocks); if (-1 == ret) { printf("Encryption failure.\n"); } else { xmlUnsetProp(device, "action"); printf("Encryption complete. Removed 'encrypt' mark from device.\n"); } }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -