⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 storage.c

📁 GNUnet是一个安全的点对点网络框架
💻 C
📖 第 1 页 / 共 2 页
字号:
        }      pos++;    }  GNUNET_free (rdir);  return GNUNET_OK;}/** * Create the directory structure for storing * a file. * * @param filename name of a file in the directory * @returns GNUNET_OK on success, GNUNET_SYSERR on failure */intGNUNET_disk_directory_create_for_file (struct GNUNET_GE_Context *ectx,                                       const char *dir){  char *rdir;  int len;  int ret;  rdir = GNUNET_expand_file_name (ectx, dir);  if (rdir == NULL)    return GNUNET_SYSERR;  len = strlen (rdir);  while ((len > 0) && (rdir[len] != DIR_SEPARATOR))    len--;  rdir[len] = '\0';  ret = GNUNET_disk_directory_create (ectx, rdir);  GNUNET_free (rdir);  return ret;}/** * Read the contents of a binary file into a buffer. * @param fileName the name of the file, not freed, *        must already be expanded! * @param len the maximum number of bytes to read * @param result the buffer to write the result to * @return the number of bytes read on success, -1 on failure */intGNUNET_disk_file_read (struct GNUNET_GE_Context *ectx,                       const char *fileName, int len, void *result){  /* open file, must exist, open read only */  int handle;  int size;  GNUNET_GE_ASSERT (ectx, fileName != NULL);  GNUNET_GE_ASSERT (ectx, len > 0);  if (len == 0)    return 0;  GNUNET_GE_ASSERT (ectx, result != NULL);  handle = GNUNET_disk_file_open (ectx, fileName, O_RDONLY, S_IRUSR);  if (handle < 0)    return -1;  size = READ (handle, result, len);  GNUNET_disk_file_close (ectx, fileName, handle);  return size;}/** * Convert string to value ('755' for chmod-call) */static intatoo (const char *s){  int n = 0;  while (('0' <= *s) && (*s < '8'))    {      n <<= 3;      n += *s++ - '0';    }  return n;}/** * Write a buffer to a file. * @param fileName the name of the file, NOT freed! * @param buffer the data to write * @param n number of bytes to write * @param mode permissions to set on the file * @return GNUNET_OK on success, GNUNET_SYSERR on error */intGNUNET_disk_file_write (struct GNUNET_GE_Context *ectx,                        const char *fileName,                        const void *buffer, unsigned int n, const char *mode){  int handle;  char *fn;  /* open file, open with 600, create if not     present, otherwise overwrite */  GNUNET_GE_ASSERT (ectx, fileName != NULL);  fn = GNUNET_expand_file_name (ectx, fileName);  handle =    GNUNET_disk_file_open (ectx, fn, O_CREAT | O_WRONLY, S_IRUSR | S_IWUSR);  if (handle == -1)    {      GNUNET_free (fn);      return GNUNET_SYSERR;    }  GNUNET_GE_ASSERT (ectx, (n == 0) || (buffer != NULL));  /* write the buffer take length from the beginning */  if (n != WRITE (handle, buffer, n))    {      GNUNET_GE_LOG_STRERROR_FILE (ectx,                                   GNUNET_GE_WARNING | GNUNET_GE_USER |                                   GNUNET_GE_IMMEDIATE, "write", fn);      GNUNET_disk_file_close (ectx, fn, handle);      GNUNET_free (fn);      return GNUNET_SYSERR;    }  GNUNET_disk_file_close (ectx, fn, handle);  if (0 != CHMOD (fn, atoo (mode)))    {      GNUNET_GE_LOG_STRERROR_FILE (ectx,                                   GNUNET_GE_WARNING | GNUNET_GE_USER |                                   GNUNET_GE_BULK, "chmod", fn);    }  GNUNET_free (fn);  return GNUNET_OK;}/** * Scan a directory for files. The name of the directory * must be expanded first (!). * @param dirName the name of the directory * @param callback the method to call for each file, *        can be NULL, in that case, we only count * @param data argument to pass to callback * @return the number of files found, GNUNET_SYSERR on error or *         ieration aborted by callback returning GNUNET_SYSERR */intGNUNET_disk_directory_scan (struct GNUNET_GE_Context *ectx,                            const char *dirName,                            GNUNET_DirectoryEntryCallback callback,                            void *data){  DIR *dinfo;  struct dirent *finfo;  struct stat istat;  int count = 0;  GNUNET_GE_ASSERT (ectx, dirName != NULL);  if (0 != STAT (dirName, &istat))    {      GNUNET_GE_LOG_STRERROR_FILE (ectx,                                   GNUNET_GE_WARNING | GNUNET_GE_USER |                                   GNUNET_GE_BULK, "stat", dirName);      return GNUNET_SYSERR;    }  if (!S_ISDIR (istat.st_mode))    {      GNUNET_GE_LOG (ectx,                     GNUNET_GE_WARNING | GNUNET_GE_USER | GNUNET_GE_BULK,                     _("Expected `%s' to be a directory!\n"), dirName);      return GNUNET_SYSERR;    }  errno = 0;  dinfo = OPENDIR (dirName);  if ((errno == EACCES) || (dinfo == NULL))    {      GNUNET_GE_LOG_STRERROR_FILE (ectx,                                   GNUNET_GE_WARNING | GNUNET_GE_USER |                                   GNUNET_GE_BULK, "opendir", dirName);      if (dinfo != NULL)        closedir (dinfo);      return GNUNET_SYSERR;    }  while ((finfo = readdir (dinfo)) != NULL)    {      if ((0 == strcmp (finfo->d_name, ".")) ||          (0 == strcmp (finfo->d_name, "..")))        continue;      if (callback != NULL)        {          if (GNUNET_OK != callback (finfo->d_name, dirName, data))            {              closedir (dinfo);              return GNUNET_SYSERR;            }        }      count++;    }  closedir (dinfo);  return count;}/** * Callback for GNUNET_disk_directory_remove */static intrmHelper (const char *fil, const char *dir, void *ctx){  struct GNUNET_GE_Context *ectx = ctx;  char *fn;  size_t n;  n = strlen (dir) + strlen (fil) + 2;  fn = GNUNET_malloc (n);  GNUNET_snprintf (fn, n, "%s/%s", dir, fil);  if (GNUNET_SYSERR == GNUNET_disk_directory_remove (ectx, fn))    {      GNUNET_free (fn);      return GNUNET_SYSERR;    }  GNUNET_free (fn);  return GNUNET_OK;}/** * Remove all files in a directory (rm -rf). Call with * caution. * * * @param fileName the file to remove * @return GNUNET_OK on success, GNUNET_SYSERR on error */intGNUNET_disk_directory_remove (struct GNUNET_GE_Context *ectx,                              const char *fileName){  struct stat istat;  if (0 != LSTAT (fileName, &istat))    return GNUNET_NO;           /* file may not exist... */  if (UNLINK (fileName) == 0)    return GNUNET_OK;  if ((errno != EISDIR) &&      /* EISDIR is not sufficient in all cases, e.g.         sticky /tmp directory may result in EPERM on BSD.         So we also explicitly check "isDirectory" */      (GNUNET_YES != GNUNET_disk_directory_test (ectx, fileName)))    {      GNUNET_GE_LOG_STRERROR_FILE (ectx,                                   GNUNET_GE_WARNING | GNUNET_GE_USER |                                   GNUNET_GE_ADMIN | GNUNET_GE_BULK, "rmdir",                                   fileName);      return GNUNET_SYSERR;    }  if (GNUNET_SYSERR ==      GNUNET_disk_directory_scan (ectx, fileName, &rmHelper, ectx))    return GNUNET_SYSERR;  if (0 != RMDIR (fileName))    {      GNUNET_GE_LOG_STRERROR_FILE (ectx,                                   GNUNET_GE_WARNING | GNUNET_GE_USER |                                   GNUNET_GE_ADMIN | GNUNET_GE_BULK, "rmdir",                                   fileName);      return GNUNET_SYSERR;    }  return GNUNET_OK;}voidGNUNET_disk_file_close (struct GNUNET_GE_Context *ectx, const char *filename,                        int fd){  if (0 != CLOSE (fd))    GNUNET_GE_LOG_STRERROR_FILE (ectx,                                 GNUNET_GE_WARNING | GNUNET_GE_USER |                                 GNUNET_GE_BULK, "close", filename);}intGNUNET_disk_file_open (struct GNUNET_GE_Context *ectx, const char *filename,                       int oflag, ...){  char *fn;  int mode;  int ret;#ifdef MINGW  char szFile[_MAX_PATH + 1];  long lRet;  if ((lRet = plibc_conv_to_win_path (filename, szFile)) != ERROR_SUCCESS)    {      errno = ENOENT;      SetLastError (lRet);      GNUNET_GE_LOG_STRERROR_FILE (ectx,                                   GNUNET_GE_WARNING | GNUNET_GE_USER |                                   GNUNET_GE_DEVELOPER | GNUNET_GE_ADMIN |                                   GNUNET_GE_BULK, "plibc_conv_to_win_path",                                   filename);      return -1;    }  fn = GNUNET_strdup (szFile);#else  fn = GNUNET_expand_file_name (ectx, filename);#endif  if (oflag & O_CREAT)    {      va_list arg;      va_start (arg, oflag);      mode = va_arg (arg, int);      va_end (arg);    }  else    {      mode = 0;    }#ifdef MINGW  /* set binary mode */  oflag |= O_BINARY;#endif  ret = OPEN (fn, oflag, mode);  if (ret == -1)    GNUNET_GE_LOG_STRERROR_FILE (ectx,                                 GNUNET_GE_WARNING | GNUNET_GE_USER |                                 GNUNET_GE_BULK, "open", fn);  GNUNET_free (fn);  return ret;}#define COPY_BLK_SIZE 65536/** * Copy a file. * @return GNUNET_OK on success, GNUNET_SYSERR on error */intGNUNET_disk_file_copy (struct GNUNET_GE_Context *ectx, const char *src,                       const char *dst){  char *buf;  unsigned long long pos;  unsigned long long size;  unsigned long long len;  int in;  int out;  if (GNUNET_OK != GNUNET_disk_file_size (ectx, src, &size, GNUNET_YES))    return GNUNET_SYSERR;  pos = 0;  in = GNUNET_disk_file_open (ectx, src, O_RDONLY | O_LARGEFILE);  if (in == -1)    return GNUNET_SYSERR;  out = GNUNET_disk_file_open (ectx,                               dst,                               O_LARGEFILE | O_WRONLY | O_CREAT | O_EXCL,                               S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP);  if (out == -1)    {      GNUNET_disk_file_close (ectx, src, in);      return GNUNET_SYSERR;    }  buf = GNUNET_malloc (COPY_BLK_SIZE);  while (pos < size)    {      len = COPY_BLK_SIZE;      if (len > size - pos)        len = size - pos;      if (len != READ (in, buf, len))        goto FAIL;      if (len != WRITE (out, buf, len))        goto FAIL;      pos += len;    }  GNUNET_free (buf);  GNUNET_disk_file_close (ectx, src, in);  GNUNET_disk_file_close (ectx, dst, out);  return GNUNET_OK;FAIL:  GNUNET_free (buf);  GNUNET_disk_file_close (ectx, src, in);  GNUNET_disk_file_close (ectx, dst, out);  return GNUNET_SYSERR;}/* end of storage.c */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -