📄 functions.c
字号:
/* GNU fdisk - a clone of Linux fdisk. Copyright (C) 2006 Free Software Foundation, Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA*/#include <stdlib.h>#include <stdio.h>#include <stdarg.h>#include <check.h>#include <sys/stat.h>#include <parted/parted.h>/* #include <endian.h> */#include <string.h>#include "../src/strlist.h"#include "functions.h"#include "../src/common.h"/* NOTE: In the comments we say that we "query" or "ask" something when we emulate user query function and pass the parameter through there *//* We can't seek more... */#define SIZE 2147483647L/* We will give the partitions below different sizes. I'll use rand */#define PART_LENGTH (2097151LL - ((unsigned int) rand() % 1048575))PedDevice *dev = NULL;PedDisk *disk = NULL;UICalls uiquery;/* We need a seed for the random functions */int seed = 1;voidset_seed(int sd) { seed = sd;}/* No chance someone else decides to call this file this way, I hope */static char tempfile[] = "/tmp/check_cfdisk_temporary_disk_drive";static char tempfile2[] = "/tmp/check_cfdisk_temporary_disk_drive2";const char *tempfile_name(){ return tempfile;}const char *tempfile2_name(){ return tempfile2;}/* We should try not to ruin a file, or more importantly, some block device */static int is_blockdev(const char *file) { struct stat file_stat; if (stat(file,&file_stat) < 0) return -1; if(S_ISBLK(file_stat.st_mode)) return 1; else return 0;}void check_safety () { int a = is_blockdev(tempfile); int b = is_blockdev(tempfile2); if (a > 0 || b > 0) { printf("ERROR: Found a block device with the name of our temp " "file. Aborting."); exit(1); } else { const char msg[] = "%s exists and will be overwritten. " "Are you sure you want to continue (y/N)?"; if (!a) { printf(msg, tempfile); if (getchar() != 'y' && getchar() != 'Y') { exit(0); } } if (!b) { printf(msg, tempfile2); if (getchar() != 'y' && getchar() != 'Y') { exit(0); } } } /* Well, there should be no problem, TODO: is it needed? */ if (!getuid() || !geteuid()) { printf("You should not run these tests as root.\n" "Are you sure you want to continue (y/N)? "); if (getchar() != 'y' && getchar() != 'Y') { exit(0); } }}/* We need an exception handler */PedExceptionOption ex_opts;PedExceptionType ex_type;char exception_error[BUFSIZE];// = "%s";static int exception_count = 0;int set_exception_error(const char *format, ...) { va_list args; char buf[BUFSIZE]; va_start(args, format); if(vsnprintf(buf, BUFSIZE, format, args) < 0) { return -1; } va_end(args); return snprintf(exception_error,BUFSIZE, "%s: %s", buf, "%s");}int reset_exception_error() { strncpy(exception_error, "%s", BUFSIZE);}PedExceptionOptionexception_handler (PedException* ex) { exception_count++; ex_opts = ex->options; ex_type = ex->type; switch (ex->type) { case PED_EXCEPTION_ERROR: case PED_EXCEPTION_FATAL: case PED_EXCEPTION_BUG: case PED_EXCEPTION_NO_FEATURE: fail(exception_error, ex->message); } if (ex_opts & PED_EXCEPTION_FIX) return PED_EXCEPTION_FIX; else if (ex_opts & PED_EXCEPTION_RETRY) return PED_EXCEPTION_RETRY; else if (ex_opts & PED_EXCEPTION_YES) return PED_EXCEPTION_YES; else if (ex_opts & PED_EXCEPTION_OK) return PED_EXCEPTION_OK; else if (ex_opts & PED_EXCEPTION_IGNORE) return PED_EXCEPTION_IGNORE; else return PED_EXCEPTION_UNHANDLED; }/* Look for functions who handled exceptions incorrectly. If this does not go to our exception handler, we have a problem. Will check this at the end of each test. */void test_exception() { //printf("\nSo far we got %d exceptions\n", exception_count); exception_count = 0; if (ped_exception_throw (PED_EXCEPTION_INFORMATION, PED_EXCEPTION_OK, "Test") != PED_EXCEPTION_OK) fail ("Exception not handled by our handler"); if (exception_count != 1) fail ("Caught %d exceptions instead of 1", exception_count);}/* This functions will return what's needed *//* NOTE: If the string is DEFAULT_STRING, we return the default string *//* Also note that we have two strings here, if the last character is 1, we should use the second string, if it is 2, we should change it to 1, and if 0, we should use the first. I know it's ugly, but it works. */char string[2][BUFSIZE+1];int string_gets;int getstring (const char* prompt, char** value, const StrList* str_list, const StrList* loc_str_list, int multi_word){ /* We count how much times this function is called */ string_gets++; /* We check whether the first or the second string should be used if there is a "queue" of two strings. */ char *s; if (string[0][BUFSIZE] == 1) { s = string[1]; string[0][BUFSIZE] = 0; } else s = string[0]; if (string[0][BUFSIZE] == 2) string[0][BUFSIZE] = 1; if (!*value || strcmp(s, DEFAULT_STRING)) { if (str_list || loc_str_list) { int found = 0; char *temp = NULL; const StrList *c; /* Check if the test string is not found in the string list */ for (c = str_list; !found && c != NULL; c = c->next) { temp = str_list_convert_node(c); if (!strcmp(temp,s)) found = 1; if (temp) free(temp); } for (c = loc_str_list; !found && c != NULL; c = c->next) { temp = str_list_convert_node(c); if (!strcmp(temp,s)) found = 1; if (temp) free(temp); } if (!found) return 0; } if (*value) ped_free (*value); *value = strdup(s); } return 1;}int integer = 0;int getint (const char* prompt, int *value){ *value = integer; return 1;}int bool = 1;int getbool (const char* prompt, int *value){ *value = bool; return 1;}PedDevice *device = NULL;int getdev (const char* prompt, PedDevice** value){ *value = device; return 1;}PedPartition *partition;int getpart (const char* prompt, PedDisk **disk, PedPartition** value){ *value = partition; return 1;}PedDiskType *disk_type;int getdisktype (const char* prompt, PedDiskType **value){ *value = disk_type; return 1;}PedFileSystemType *fs_type;int getfstype (const char* prompt, PedFileSystemType **value){ *value = fs_type; return 1;}int partpos;int pos_gets;char pos_poss[POS_POSS_SIZE];int getpartpos (const char* prompt, const void* context, const char *possibilities){ /* We count how much times this was called */ pos_gets++; /* And save the possibilities */ strncpy(pos_poss, possibilities, sizeof(pos_poss)); return partpos;}intinit_tempfile() { int i; FILE *fp; fp = fopen(tempfile,"w"); if (!fp) return 0; fseek (fp, SIZE, SEEK_SET); /* NOTE: We want a ~21 GB file, this takes about 22 MB from the disk, this should be 41943039s */ for (i = 0; i < 9; i++) { fseek (fp, SIZE, SEEK_CUR); } fwrite ("", 1, 1, fp); fclose (fp); return 1; }voidunlink_tempfile() { unlink(tempfile);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -