opendir 在 C 语言上没有得到缓冲区字符 * 的内容?



我试图在Linux上使用C语言中的 opendir/readdir 函数从给定目录中读取文件,如果文件满足某些参数(如大小和类型(将被复制到某个目录,从中读取文件的目录以及从".ini">文件中读取目标和大小,问题是当我使用opendir时,即opendir(argv[1](没有问题,但是,如果我将".ini">文件中的值获取到名为search_path的字符 * 中,并将其作为OpenDir(search_path( 传递给OpenDir,则代码不起作用,我收到消息"没有这样的文件或目录">,这是代码:

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/sendfile.h>
#include <fcntl.h>
#include <dirent.h>
#include <string.h>
#include <stdint.h>
#include <unistd.h>
#include "minIni.h"

#define sizearray(a) (sizeof(a) / sizeof((a)[0]))
/*Default values for minIni library function ini_gets*/
#define DEFAULT_FILE_SIZE "100000"
#define DEFAULT_FIREFOX_CACHE "~/.cache/mozilla/firefox/43ty8soo.default-release/cache2/entries/"
#define DEFAULT_CHROMIUM_CACHE "~/.cache/chromium/Default/Cache/"
#define DEFAULT_DEST_DIR "/home/newbee/found/"
/*Utility functions*/
void error(const char *s);
int OSCopyFile(const char *, const char *);
int interesting(char *);
int filesize(char *);
int get_config(char *browser, int *min_filesize, char *cache_dir, char *dest);
int main(int argc, char * argv[]){
if (argc < 2) {
fprintf(stderr, "Usage: %s <browser-name>n", argv[0]);
exit(EXIT_FAILURE);
}
/*the only argument to the program is the browser in which cache*/
/*we want the exploration.*/
char *browser_name = argv[1];
/*Here i call get_config, that function returns the minimum size for*/
/*the files (min_file_size), where to search (cache), and where to*/
/*put the files that met the requirements (dest_dir_conf).*/
char *cache = malloc(PATH_MAX);
char *dest_dir_conf = malloc(PATH_MAX);
int min_file_size;
int result_config = get_config(
browser_name, &min_file_size, cache, dest_dir_conf);
if (result_config != 1)
exit(EXIT_FAILURE);
DIR *dir;
struct dirent *ent;
printf("[DEBUG] %sn", cache);
/*And there is the problem, no matters if i pass the 'cache' variable*/
/*or if i harcoded a string here, opendir failed and error is:*/
/*No such file or directory*/
chdir(cache);
dir = opendir(cache);
if (dir == NULL)
error("Error");
char *dest = NULL;
int count = 0;
while ((ent = readdir(dir)) != NULL) {
if ((strcmp(ent->d_name, ".") != 0) && (strcmp(ent->d_name, "..") != 0)) {
/*The interesting function determine if the file is of a given type and*/
/*return 1 if true, and 0 if not.*/
if ((interesting(ent->d_name))
&& (filesize(ent->d_name) >= min_file_size)) {
dest = malloc(strlen(dest_dir_conf) + strlen(ent->d_name));
strcpy(dest, dest_dir_conf);
strcat(dest, ent->d_name);
OSCopyFile(ent->d_name, dest);
count++;
}
}
}
closedir(dir);
printf("[Job finish, %d files was copied.]n", count);
return EXIT_SUCCESS;
}
/** errors info. **/
void error(const char *s) {
perror(s);
exit(EXIT_FAILURE);
}
/** get the file size. **/
int filesize(char *archivo) {
FILE *fp;
long fsize;
fp = fopen(archivo, "r");
if (fp) {
fseek(fp, 0L, SEEK_END);
fsize = ftell(fp);
fclose(fp);
return fsize;
} 
return -1;
}
/** copy files. **/
int OSCopyFile(const char *source, const char *destination) {
int input, output;
if ((input = open(source, O_RDONLY)) == -1)
return -1;
if ((output = creat(destination, 0660)) == -1) {
close(input);
return EXIT_FAILURE;
}
#if defined(__APPLE__) || defined(__FreeBSD__)
int result = fcopyfile(input, output, 0, COPYFILE_ALL);
#else
off_t bytesCopied = 0;
struct stat fileinfo = {0};
fstat(input, &fileinfo);
int result = sendfile(output, input, &bytesCopied, fileinfo.st_size);
#endif
close(input);
close(output);
return result;
}
/** determine if the file is interesting (for me, at least ;) ). **/
int interesting(char *filename) {
uint16_t type;
FILE *f = fopen(filename, "r");
if (!f) {
printf("Error opening file '%s'.n", filename);
return 0;
}
fread(&type, sizeof(uint16_t), 1, f);
fclose(f);
switch (type) {
case 0xD8FF:      // jpg
case 0x5089:      // png
case 0x4D42:      // bmp
case 0x4952:      // webp
case 0x4947:      // gif
case 0x3F3C:      // possible svg.
case 0x0000:      // possible mp4.
case 0x5025:      // pdf.
return 1;
default:          // not interesting.
return 0;
}
}
/*Gets the configuration from a INI file*/
int get_config(
char *browser, int *min_filesize, char *cache_dir, char *dest) {
const char ini_file[] = "config.ini";
char filesize_conf[100];
long entry_length;
entry_length = ini_gets("settings", "image_size_bytes", DEFAULT_FILE_SIZE,
filesize_conf, sizearray(filesize_conf), ini_file);
*min_filesize = atoi(filesize_conf);
if (strcmp(browser, "firefox") == 0)
entry_length = ini_gets("settings", "firefox_cache",
DEFAULT_FIREFOX_CACHE, cache_dir, 255, ini_file);
else if (strcmp(browser, "chromium") == 0)
entry_length = ini_gets("settings", "chromium_cache",
DEFAULT_CHROMIUM_CACHE, cache_dir, 255, ini_file);
else {
fprintf(stderr,
"There is no configuration for %s browser.n", browser);
exit(EXIT_FAILURE);
}
entry_length = ini_gets("settings", "destination_dir", DEFAULT_DEST_DIR,
dest, 255, ini_file);
if (entry_length <= 0)
return 0;
return 1;
}

还有问题,如果我传递"缓存">变量没关系 或者,如果我在这里对字符串进行编码,OpenDir 失败,错误为:没有这样的文件或目录

dir = opendir(cache);

读取".ini">文件的代码来自 https://www.compuphase.com/minini.htm,我在这方面有点新手,但我学得很快,所以请帮我一把。

当我使用 opendir 时,即 opendir(argv[1]( 没有问题

这是因为argv[1]包含~/.cache/...扩展版本,这要归功于在启动可执行文件之前调用 shell 的评估。

但是将像~/.cache/...这样的路径传递给opendir不起作用:C 库不会计算用户目录或环境变量~

您可以通过显式测试~并替换为getenv("HOME")来使其兼容,类似于以下非常不安全(但有效(的代码:

const char *s = "~/.cache/.something";
...
char aux[1024];
if (s[0]=='~')
{
sprintf(aux,"%s%s",getenv("HOME"),s+1);
s = aux;
}

现在,如果s~if 开头,则将评估并替换为(将指向(aux

如果必须将变量返回给调用方,则最好使用malloc来分配字符串,即使不进行替换(稍后free(。这不是重点,但是在C中正确处理字符串总是很棘手。

最新更新