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

📄 hcache.c

📁 mutt-1.5.12 源代码。linux 下邮件接受的工具。
💻 C
📖 第 1 页 / 共 2 页
字号:
}static intcrc32_matches(const char *d, unsigned int crc){  int off = sizeof (validate);  unsigned int mycrc = 0;  if (!d)    return 0;  restore_int(&mycrc, (unsigned char *) d, &off);  return (crc == mycrc);}/* Append md5sumed folder to path if path is a directory. */static const char *mutt_hcache_per_folder(const char *path, const char *folder){  static char mutt_hcache_per_folder_path[_POSIX_PATH_MAX];  struct stat path_stat;  MD5_CTX md5;  unsigned char md5sum[16];  int ret;  ret = stat(path, &path_stat);  if (ret < 0)    return path;  if (!S_ISDIR(path_stat.st_mode))    return path;  MD5Init(&md5);  MD5Update(&md5, (unsigned char *) folder, strlen(folder));  MD5Final(md5sum, &md5);  ret = snprintf(mutt_hcache_per_folder_path, _POSIX_PATH_MAX,		 "%s/%02x%02x%02x%02x%02x%02x%02x%02x"		 "%02x%02x%02x%02x%02x%02x%02x%02x",		 path, md5sum[0], md5sum[1], md5sum[2], md5sum[3],		 md5sum[4], md5sum[5], md5sum[6], md5sum[7], md5sum[8],		 md5sum[9], md5sum[10], md5sum[11], md5sum[12],		 md5sum[13], md5sum[14], md5sum[15]);  if (ret <= 0)    return path;  return mutt_hcache_per_folder_path;}/* This function transforms a header into a char so that it is useable by * db_store */static void *mutt_hcache_dump(header_cache_t *h, HEADER * header, int *off,		 unsigned long uid_validity){  unsigned char *d = NULL;  *off = 0;  d = lazy_malloc(sizeof (validate));  if (uid_validity)    memcpy(d, &uid_validity, sizeof (unsigned long));  else  {    struct timeval now;    gettimeofday(&now, NULL);    memcpy(d, &now, sizeof (struct timeval));  }  *off += sizeof (validate);  d = dump_int(h->crc, d, off);  lazy_realloc(&d, *off + sizeof (HEADER));  memcpy(d + *off, header, sizeof (HEADER));  *off += sizeof (HEADER);  d = dump_envelope(header->env, d, off);  d = dump_body(header->content, d, off);  d = dump_char(header->maildir_flags, d, off);  return d;}HEADER *mutt_hcache_restore(const unsigned char *d, HEADER ** oh){  int off = 0;  HEADER *h = mutt_new_header();  /* skip validate */  off += sizeof (validate);  /* skip crc */  off += sizeof (unsigned int);  memcpy(h, d + off, sizeof (HEADER));  off += sizeof (HEADER);  h->env = mutt_new_envelope();  restore_envelope(h->env, d, &off);  h->content = mutt_new_body();  restore_body(h->content, d, &off);  restore_char(&h->maildir_flags, d, &off);  /* this is needed for maildir style mailboxes */  if (oh)  {    h->old = (*oh)->old;    h->path = safe_strdup((*oh)->path);    mutt_free_header(oh);  }  return h;}void *mutt_hcache_fetch(header_cache_t *h, const char *filename,		  size_t(*keylen) (const char *fn)){  void* data;  data = mutt_hcache_fetch_raw (h, filename, keylen);  if (!data || !crc32_matches(data, h->crc))  {    FREE(&data);    return NULL;  }    return data;}void *mutt_hcache_fetch_raw (header_cache_t *h, const char *filename,                       size_t(*keylen) (const char *fn)){#ifndef HAVE_DB4  char path[_POSIX_PATH_MAX];  int ksize;#endif#ifdef HAVE_QDBM  char *data = NULL;#elif HAVE_GDBM  datum key;  datum data;#elif HAVE_DB4  DBT key;  DBT data;#endif    if (!h)    return NULL;  #ifdef HAVE_DB4  filename++;			/* skip '/' */  mutt_hcache_dbt_init(&key, (void *) filename, keylen(filename));  mutt_hcache_dbt_empty_init(&data);  data.flags = DB_DBT_MALLOC;    h->db->get(h->db, NULL, &key, &data, 0);    return data.data;#else  strncpy(path, h->folder, sizeof (path));  safe_strcat(path, sizeof (path), filename);  ksize = strlen (h->folder) + keylen (path + strlen (h->folder));  #endif#ifdef HAVE_QDBM  data = vlget(h->db, path, ksize, NULL);    return data;#elif HAVE_GDBM  key.dptr = path;  key.dsize = ksize;    data = gdbm_fetch(h->db, key);    return data.dptr;#endif}intmutt_hcache_store(header_cache_t *h, const char *filename, HEADER * header,		  unsigned long uid_validity,		  size_t(*keylen) (const char *fn)){  char* data;  int dlen;  int ret;    if (!h)    return -1;    data = mutt_hcache_dump(h, header, &dlen, uid_validity);  ret = mutt_hcache_store_raw (h, filename, data, dlen, keylen);    FREE(&data);    return ret;}intmutt_hcache_store_raw (header_cache_t* h, const char* filename, void* data,                       size_t dlen, size_t(*keylen) (const char* fn)){#ifndef HAVE_DB4  char path[_POSIX_PATH_MAX];  int ksize;#endif#if HAVE_GDBM  datum key;  datum databuf;#elif HAVE_DB4  DBT key;  DBT databuf;#endif    if (!h)    return -1;#if HAVE_DB4  filename++;			/* skip '/' */    mutt_hcache_dbt_init(&key, (void *) filename, keylen(filename));    mutt_hcache_dbt_empty_init(&databuf);  databuf.flags = DB_DBT_USERMEM;  databuf.data = data;  databuf.size = dlen;  databuf.ulen = dlen;    return h->db->put(h->db, NULL, &key, &databuf, 0);#else  strncpy(path, h->folder, sizeof (path));  safe_strcat(path, sizeof (path), filename);  ksize = strlen(h->folder) + keylen(path + strlen(h->folder));#endif#if HAVE_QDBM  return vlput(h->db, path, ksize, data, dlen, VL_DOVER);#elif HAVE_GDBM  key.dptr = path;  key.dsize = ksize;    databuf.dsize = dlen;  databuf.dptr = data;    return gdbm_store(h->db, key, databuf, GDBM_REPLACE);#endif}#if HAVE_QDBMheader_cache_t *mutt_hcache_open(const char *path, const char *folder){  struct header_cache *h = safe_calloc(1, sizeof (HEADER_CACHE));  int    flags = VL_OWRITER | VL_OCREAT;  h->db = NULL;  h->folder = safe_strdup(folder);  h->crc = generate_crc32();  if (!path || path[0] == '\0')  {    FREE(&h->folder);    FREE(&h);    return NULL;  }  path = mutt_hcache_per_folder(path, folder);  if (option(OPTHCACHECOMPRESS))    flags |= VL_OZCOMP;  h->db = vlopen(path, flags, VL_CMPLEX);  if (h->db)    return h;  else  {    FREE(&h->folder);    FREE(&h);    return NULL;  }}voidmutt_hcache_close(header_cache_t *h){  if (!h)    return;  vlclose(h->db);  FREE(&h->folder);  FREE(&h);}intmutt_hcache_delete(header_cache_t *h, const char *filename,		   size_t(*keylen) (const char *fn)){  char path[_POSIX_PATH_MAX];  int ksize;  if (!h)    return -1;  strncpy(path, h->folder, sizeof (path));  safe_strcat(path, sizeof (path), filename);  ksize = strlen(h->folder) + keylen(path + strlen(h->folder));  return vlout(h->db, path, ksize);}#elif HAVE_GDBMheader_cache_t *mutt_hcache_open(const char *path, const char *folder){  struct header_cache *h = safe_calloc(1, sizeof (HEADER_CACHE));  int pagesize = atoi(HeaderCachePageSize) ? atoi(HeaderCachePageSize) : 16384;  h->db = NULL;  h->folder = safe_strdup(folder);  h->crc = generate_crc32();  if (!path || path[0] == '\0')  {    FREE(&h->folder);    FREE(&h);    return NULL;  }  path = mutt_hcache_per_folder(path, folder);  h->db = gdbm_open((char *) path, pagesize, GDBM_WRCREAT, 00600, NULL);  if (h->db)    return h;  /* if rw failed try ro */  h->db = gdbm_open((char *) path, pagesize, GDBM_READER, 00600, NULL);  if (h->db)    return h;  else  {    FREE(&h->folder);    FREE(&h);    return NULL;  }}voidmutt_hcache_close(header_cache_t *h){  if (!h)    return;  gdbm_close(h->db);  FREE(&h->folder);  FREE(&h);}intmutt_hcache_delete(header_cache_t *h, const char *filename,		   size_t(*keylen) (const char *fn)){  datum key;  char path[_POSIX_PATH_MAX];  if (!h)    return -1;  strncpy(path, h->folder, sizeof (path));  safe_strcat(path, sizeof (path), filename);  key.dptr = path;  key.dsize = strlen(h->folder) + keylen(path + strlen(h->folder));  return gdbm_delete(h->db, key);}#elif HAVE_DB4static voidmutt_hcache_dbt_init(DBT * dbt, void *data, size_t len){  dbt->data = data;  dbt->size = dbt->ulen = len;  dbt->dlen = dbt->doff = 0;  dbt->flags = DB_DBT_USERMEM;}static voidmutt_hcache_dbt_empty_init(DBT * dbt){  dbt->data = NULL;  dbt->size = dbt->ulen = dbt->dlen = dbt->doff = 0;  dbt->flags = 0;}header_cache_t *mutt_hcache_open(const char *path, const char *folder){  struct stat sb;  u_int32_t createflags = DB_CREATE;  int ret;  struct header_cache *h = calloc(1, sizeof (HEADER_CACHE));  int pagesize = atoi(HeaderCachePageSize);  h->crc = generate_crc32();  if (!path || path[0] == '\0')  {    FREE(&h);    return NULL;  }  path = mutt_hcache_per_folder(path, folder);  snprintf(h->lockfile, _POSIX_PATH_MAX, "%s-lock-hack", path);  h->fd = open(h->lockfile, O_WRONLY | O_CREAT, S_IRUSR | S_IWUSR);  if (h->fd < 0)  {    FREE(&h);    return NULL;  }  if (mx_lock_file(h->lockfile, h->fd, 1, 0, 5))  {    close(h->fd);    FREE(&h);    return NULL;  }  ret = db_env_create(&h->env, 0);  if (ret)  {    mx_unlock_file(h->lockfile, h->fd, 0);    close(h->fd);    FREE(&h);    return NULL;  }  ret = (*h->env->open)(h->env, NULL, DB_INIT_MPOOL | DB_CREATE | DB_PRIVATE,	0600);  if (!ret)  {    ret = db_create(&h->db, h->env, 0);    if (ret)    {      h->env->close(h->env, 0);      mx_unlock_file(h->lockfile, h->fd, 0);      close(h->fd);      FREE(&h);      return NULL;    }  }  if (stat(path, &sb) != 0 && errno == ENOENT)  {    createflags |= DB_EXCL;    h->db->set_pagesize(h->db, pagesize);  }  ret = (*h->db->open)(h->db, NULL, path, folder, DB_BTREE, createflags, 0600);  if (ret)  {    h->db->close(h->db, 0);    h->env->close(h->env, 0);    mx_unlock_file(h->lockfile, h->fd, 0);    close(h->fd);    FREE(&h);    return NULL;  }  return h;}voidmutt_hcache_close(header_cache_t *h){  if (!h)    return;  h->db->close(h->db, 0);  h->env->close(h->env, 0);  mx_unlock_file(h->lockfile, h->fd, 0);  close(h->fd);  FREE(&h);}intmutt_hcache_delete(header_cache_t *h, const char *filename,		   size_t(*keylen) (const char *fn)){  DBT key;  if (!h)    return -1;  filename++;			/* skip '/' */  mutt_hcache_dbt_init(&key, (void *) filename, keylen(filename));  return h->db->del(h->db, NULL, &key, 0);}#endif

⌨️ 快捷键说明

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