因为我还是编程新手,请耐心等待。我正在尝试读取一个文件并将其上下文存储为变量,这是我的代码我很抱歉,如果它很长:
#define _BSD_SOURCE
#include <stdio.h>
#include <sys/stat.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <time.h>
// CEK ROUTER MODEL
char* router_model;
char* model() {
char filename[] = "/proc/cpuinfo";
char* key = "system type";
char* value;
FILE *file = fopen(filename, "r");
if (file != NULL) {
char line[1000];
while (fgets(line, sizeof line, file) != NULL) /* read a line from a file */ {
//fprintf(stdout, "%s", line); //print the file contents on stdout.
if (strncmp(line, key, strlen(key)) == 0) {
char* value = strchr(line, ':');
value += 2;
router_model = strdup(value);
break; // once the key has been found we can stop reading
}
}
fclose(file);
}
else {
perror(filename); //print the error message on stderr.
}
return router_model;
}
// TULIS SERIAL NUMBER KE FILE
char tulis(char p[100]) {
// Write a serial number to a file
char sn[30];
char encrypt_sn[50];
printf("Serial Number:\n");
scanf("%s", sn);
FILE *f = fopen("/usr/share/terminfo/f/fsn-55cfc8770b69cc07268fae7f25ee444c", "w");
if (f == NULL) {
printf("Error opening file!\n");
exit(1);
}
fprintf(f,"Serial Number: %s", sn);
fclose(f);
sprintf(encrypt_sn, "ccrypt -e /usr/share/terminfo/f/fsn-55cfc8770b69cc07268fae7f25ee444c -K %s", p);
system(encrypt_sn);
system("mv /usr/share/terminfo/f/fsn-55cfc8770b69cc07268fae7f25ee444c.cpt /usr/share/terminfo/f/fsn-55cfc8770b69cc07268fae7f25ee444c");
printf("Serial number is saved in /usr/share/terminfo/f/fsn-55cfc8770b69cc07268fae7f25ee444c\n");
return 0;
}
// BACA SERIAL NUMBER & SIMPAN DALAM SEBUAH VARIABLE
char baca(char p[100]) {
// Store the serial number from a file in a variable
char line[50];
char decrypt_sn[50];
char key[30] = "Serial Number";
char *serial_number;
if( access( "/usr/share/terminfo/f/fsn-55cfc8770b69cc07268fae7f25ee444c", F_OK ) != -1 ) {
system("cp /usr/share/terminfo/f/fsn-55cfc8770b69cc07268fae7f25ee444c /tmp/");
system("mv /tmp/fsn-55cfc8770b69cc07268fae7f25ee444c /tmp/fsn-55cfc8770b69cc07268fae7f25ee444c.cpt");
sprintf(decrypt_sn, "ccrypt -d /tmp/fsn-55cfc8770b69cc07268fae7f25ee444c.cpt -K %s", p);
system(decrypt_sn);
FILE *file = fopen("/tmp/fsn-55cfc8770b69cc07268fae7f25ee444c", "r");
if (file == NULL) {
printf("Error opening file!\n");
exit(1);
}
while (fgets(line, sizeof line, file) != NULL) /* read a line from a file */ {
//fprintf(stdout, "%s", line); //print the file contents on stdout.
if (strncmp(line, key, strlen(key)) == 0) {
char* value = strchr(line, ':');
value += 2;
serial_number = strdup(value);
break; // once the key has been found we can stop reading
}
}
fclose(file);
//printf("Your hardware serial number is: (%s)\n", serial_number);
remove("/tmp/fsn-55cfc8770b69cc07268fae7f25ee444c");
}
else {
printf("fsn not found\n");
return -1;
}
return 0;
}
int main(int argc, char* argv[]) {
char *r;
char *del;
char *decrypt;
int ret;
char input[30];
char *p;
char *original_sn;
p = "MmI4MTUxM2FjMjRlMDkzYmRkZGQyMjcwMjQ4OWY3MDAwNGZiYTM0MWNkZGIxNTdlYzAxN2";
//tulis(p);
original_sn = baca(p);
printf("SN: %s", original_sn);
return 0;
}
我尝试阅读的文件是/usr/share/terminfo/f/fsn-55cfc8770b69cc07268fae7f25ee444c
,在使用ccrypt
解密后,该文件的内容为Serial Number: 1866203214226041
。我想将1866203214226041
存储为变量,但在运行该代码时我得到Segmentation Fault
,我该如何解决?
答案 0 :(得分:0)
只需查看从您的代码中提取的代码段:
while (fgets(line, sizeof line, file) != NULL) /* read a line from a file */ {
//fprintf(stdout, "%s", line); //print the file contents on stdout.
if (strncmp(line, key, strlen(key)) == 0) {
char* value = strchr(line, ':');
value += 2;
router_model = strdup(value);
break; // once the key has been found we can stop reading
}
}
首先,您不检查strchr(line, ':');
返回的值,因为如果字符串以NULL
开头但没有{{1},您将获得system type
它上面有char。你假设它总是会找到一个':'
和增量两个值(如果它没有找到char,它将生成一个指向页面零的位置':'
的指针mem(通常暗示2
来自SIGSEGV
调用的strdup(3)
信号。)此外,在2
递增后,您可以跳过最后\0
个字符,如果':'
字符恰好是该行的最后一行。
最后的评论。正确地,在顶部初始化key
会使while
循环更有效,在循环内调用strlen(key)
会使代码找到{{1}指向的字符串的结尾在每次循环迭代中,获取字符串长度。最好在循环外预先计算key
(因为它是常量)并在strlen(key)
语句中使用该值,如下所示:
if
另一件事是:当你打印那么大的字符串时,不要为 size_t key_length = strlen(key);
while (fgets(line, sizeof line, file) != NULL) /* read a line from a file */ {
//fprintf(stdout, "%s", line); //print the file contents on stdout.
if (strncmp(line, key, key_length) == 0) {
char* value = strchr(line, ':');
if (value) { // only if value is != NULL should we continue
value += 1; // we are not sure if after ':' we'll have a null char `\0` so better do a +1 increment.
router_model = strdup(value);
break; // once the key has been found we can stop reading
}
}
}
使用如此短的字符串数组(只有50个字符空间用于最多49个长度的空终止字符串)(我认为只有格式因为你正在使用自己的代码在缓冲区溢出中运行,所以已经比那些[编辑]大约75个字符[/ edit]更长了。这可能是encrypt_sn
的另一个来源。
不再对您的代码进行检查,但可以更多。我认为稍后SIGSEGV
会发生同样的问题。
还有一个问题:如果您的来源不再是bsd来源,为什么要将您的来源标记为decrypt_sn
? (在bsd系统中没有_BSD_SOURCE
,在bsd系统中没有procfs
我尝试检查我的debian amd64系统的/proc/cpuinfo
文件,但没有找到/proc/cpuinfo
字段。