opendir无法获取C语言上的缓冲区char *的内容? [英] opendir dont get content of buffer char * on C language?

查看:112
本文介绍了opendir无法获取C语言上的缓冲区char *的内容?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图使用 Linux C opendir / readdir 函数从给定目录中读取文件,如果文件满足某些参数,例如大小和类型将被复制到某些目录,从中读取文件的目录以及从。ini 文件读取的目的地和大小,问题是当我使用 opendir时与ie opendir(argv [1])没问题,但是如果我将。ini 文件中的值转换为char *称为ie search_path 并将其作为 opendir(search_path)传递给 opendir
代码不起作用,我收到消息 没有此类文件或目录 ,代码如下:

Im trying to read files from a given directory using opendir/readdir functions from C on Linux, if the files meet certain parameters like size and type will be copied to certain directory, the directory from where files are read and the destination and the size are read from an ".ini" file, the problem is when i use opendir with i.e opendir(argv[1]) there is no problem, but if i get the value from ".ini" file into a char * called i.e search_path and pass it to opendir as opendir(search_path) the code don't work and i get the message "No such file or directory", here is the code:

#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] %s\n", 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;
}

还有问题,如果我通过了'cache'变量
,或者如果我在此处编码了一个字符串,则opendir失败,错误是:
没有这样的文件或目录

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

  dir = opendir(cache);

读取。ini 文件的代码来自 https://www.compuphase.com/minini.htm ,在这个过程中我有点新手,但我学到了

The code for read ".ini" files is from https://www.compuphase.com/minini.htm, im a little newbee in this but i learn quickly, so please give me a hand with that.

推荐答案


当我将opendir与opendir一起使用时(argv [1])没问题

when i use opendir with i.e opendir(argv[1]) there is no problem

这是因为 argv [1] 包含扩展的版本的〜/ .cache /...,这要归功于调用shell 之前

That's because argv[1] contains the expanded version of ~/.cache/... thanks to evaluation by the calling shell before the executable is started.

但是将〜/ .cache /...这样的路径传递给 opendir 不起作用:C库无法对用户目录或环境变量进行评估。

But passing a path like ~/.cache/... to opendir doesn't work: C library does not evaluate ~ to user directory or environment variables.

您可以通过显式测试并用 getenv( HOME),这样的东西很不安全(b代码):

You could make it compatible by testing for ~ explicitly and replacing by getenv("HOME"), something like this quite unsafe (but working) code:

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

现在是否 s 开始,如果将被评估并替换为(将指向) aux

now if s starts by ~ if will be evaluated and replaced by (will point to) aux.

如果必须将变量返回给调用者,则最好使用 malloc 分配字符串,即使不进行替换(和免费)。这不是重点,但是在C语言中正确的字符串处理总是很棘手。

if the variable must be returned to a caller, better use malloc to allocate the string even if no substitution is to be made (and free it later). That's not the point, but proper string handling in C is always tricky.

这篇关于opendir无法获取C语言上的缓冲区char *的内容?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆