-rw-r--r-- | kmicromail/libetpan/mh/mailmh.c | 473 |
1 files changed, 239 insertions, 234 deletions
diff --git a/kmicromail/libetpan/mh/mailmh.c b/kmicromail/libetpan/mh/mailmh.c index 5e2b4cc..1087ce1 100644 --- a/kmicromail/libetpan/mh/mailmh.c +++ b/kmicromail/libetpan/mh/mailmh.c @@ -239,406 +239,411 @@ struct mailmh_folder * mailmh_folder_find(struct mailmh_folder * root, #if 0 r = mailmh_folder_update(root); if (r != MAILMH_NO_ERROR) return NULL; #endif #if 0 for(i = 0 ; i < root->fl_subfolders_tab->len ; i++) { struct mailmh_folder * subfolder; subfolder = carray_get(root->fl_subfolders_tab, i); if (subfolder != NULL) if (strncmp(subfolder->fl_filename, filename, strlen(subfolder->fl_filename)) == 0) return mailmh_folder_find(subfolder, filename); } #endif strncpy(pathname, filename, PATH_MAX); pathname[PATH_MAX - 1] = 0; start = pathname + strlen(root->fl_filename) + 1; p = strchr(start, MAIL_DIR_SEPARATOR); if (p != NULL) { * p = 0; root = mailmh_folder_find(root, pathname); if (root != NULL) { folder = mailmh_folder_find(root, filename); if (folder == NULL) return NULL; return folder; } return NULL; } else { key.data = pathname; key.len = strlen(pathname); r = chash_get(root->fl_subfolders_hash, &key, &data); if (r < 0) return NULL; return data.data; } } int mailmh_folder_update(struct mailmh_folder * folder) { - DIR * d; - struct dirent * ent; - struct stat buf; - char * mh_seq; - char filename[PATH_MAX]; - int res; - int r; - uint32_t max_index; + DIR * d; + struct dirent * ent; + struct stat buf; + char * mh_seq; + char filename[PATH_MAX]; + int res; + int r; + uint32_t max_index; #if 0 - int add_folder; + int add_folder; #endif - unsigned int i; + unsigned int i; - if (stat(folder->fl_filename, &buf) == -1) { - res = MAILMH_ERROR_FOLDER; - goto err; - } + if (stat(folder->fl_filename, &buf) == -1) { + res = MAILMH_ERROR_FOLDER; + goto err; + } - if (folder->fl_mtime == buf.st_mtime) { - res = MAILMH_NO_ERROR; - goto err; - } + if (folder->fl_mtime == buf.st_mtime) { + res = MAILMH_NO_ERROR; + goto err; + } - folder->fl_mtime = buf.st_mtime; + folder->fl_mtime = buf.st_mtime; - d = opendir(folder->fl_filename); - if (d == NULL) { - res = MAILMH_ERROR_FOLDER; - goto err; - } + d = opendir(folder->fl_filename); + if (d == NULL) { + res = MAILMH_ERROR_FOLDER; + goto err; + } - max_index = 0; + max_index = 0; #if 0 - if (folder->fl_subfolders_tab->len == 0) - add_folder = 1; - else - add_folder = 0; + if (folder->fl_subfolders_tab->len == 0) + add_folder = 1; + else + add_folder = 0; #endif - /* clear the message list */ + /* clear the message list */ - for(i = 0 ; i < carray_count(folder->fl_msgs_tab) ; i ++) { - struct mailmh_msg_info * msg_info; - chashdatum key; + for(i = 0 ; i < carray_count(folder->fl_msgs_tab) ; i ++) { + struct mailmh_msg_info * msg_info; + chashdatum key; - msg_info = carray_get(folder->fl_msgs_tab, i); - if (msg_info == NULL) - continue; + msg_info = carray_get(folder->fl_msgs_tab, i); + if (msg_info == NULL) + continue; #if 0 - cinthash_remove(folder->fl_msgs_hash, msg_info->msg_index); + cinthash_remove(folder->fl_msgs_hash, msg_info->msg_index); #endif - key.data = &msg_info->msg_index; - key.len = sizeof(msg_info->msg_index); - chash_delete(folder->fl_msgs_hash, &key, NULL); + key.data = &msg_info->msg_index; + key.len = sizeof(msg_info->msg_index); + chash_delete(folder->fl_msgs_hash, &key, NULL); - mailmh_msg_info_free(msg_info); - } + mailmh_msg_info_free(msg_info); + } - carray_set_size(folder->fl_msgs_tab, 0); + carray_set_size(folder->fl_msgs_tab, 0); - do { - uint32_t index; + do { + uint32_t index; - ent = readdir(d); + ent = readdir(d); - if (ent != NULL) { + if (ent != NULL) { - snprintf(filename, PATH_MAX, - "%s%c%s", folder->fl_filename, MAIL_DIR_SEPARATOR, ent->d_name); + snprintf(filename, PATH_MAX, + "%s%c%s", folder->fl_filename, MAIL_DIR_SEPARATOR, ent->d_name); - if (stat(filename, &buf) == -1) - continue; + if (stat(filename, &buf) == -1) + continue; - if (S_ISREG(buf.st_mode)) { - index = strtoul(ent->d_name, NULL, 10); - if (index != 0) { - struct mailmh_msg_info * msg_info; - unsigned int array_index; - chashdatum key; - chashdatum data; + if (S_ISREG(buf.st_mode)) { + index = strtoul(ent->d_name, NULL, 10); + if (index != 0) { + struct mailmh_msg_info * msg_info; + unsigned int array_index; + chashdatum key; + chashdatum data; - msg_info = mailmh_msg_info_new(index, buf.st_size, buf.st_mtime); - if (msg_info == NULL) { - res = MAILMH_ERROR_MEMORY; - goto closedir; - } + msg_info = mailmh_msg_info_new(index, buf.st_size, buf.st_mtime); + if (msg_info == NULL) { + res = MAILMH_ERROR_MEMORY; + goto closedir; + } - r = carray_add(folder->fl_msgs_tab, msg_info, &array_index); - if (r < 0) { - mailmh_msg_info_free(msg_info); - res = MAILMH_ERROR_MEMORY; - goto closedir; - } - msg_info->msg_array_index = array_index; + r = carray_add(folder->fl_msgs_tab, msg_info, &array_index); + if (r < 0) { + mailmh_msg_info_free(msg_info); + res = MAILMH_ERROR_MEMORY; + goto closedir; + } + msg_info->msg_array_index = array_index; - if (index > max_index) - max_index = index; + if (index > max_index) + max_index = index; #if 0 - r = cinthash_add(folder->fl_msgs_hash, msg_info->msg_index, msg_info); + r = cinthash_add(folder->fl_msgs_hash, msg_info->msg_index, msg_info); #endif - key.data = &msg_info->msg_index; - key.len = sizeof(msg_info->msg_index); - data.data = msg_info; - data.len = 0; + key.data = &msg_info->msg_index; + key.len = sizeof(msg_info->msg_index); + data.data = msg_info; + data.len = 0; - r = chash_set(folder->fl_msgs_hash, &key, &data, NULL); - if (r < 0) { - carray_delete_fast(folder->fl_msgs_tab, msg_info->msg_array_index); - mailmh_msg_info_free(msg_info); - res = MAILMH_ERROR_MEMORY; - goto closedir; - } - } - } - else if (S_ISDIR(buf.st_mode)) { - struct mailmh_folder * subfolder; - unsigned int array_index; - chashdatum key; - chashdatum data; - - if (ent->d_name[0] == '.') { - if (ent->d_name[1] == 0) - continue; - if ((ent->d_name[1] == '.') && (ent->d_name[2] == 0)) - continue; - } - - key.data = ent->d_name; - key.len = strlen(ent->d_name); - r = chash_get(folder->fl_subfolders_hash, &key, &data); - if (r < 0) { - subfolder = mailmh_folder_new(folder, ent->d_name); - if (subfolder == NULL) { - res = MAILMH_ERROR_MEMORY; - goto closedir; - } + r = chash_set(folder->fl_msgs_hash, &key, &data, NULL); + if (r < 0) { + carray_delete_fast(folder->fl_msgs_tab, msg_info->msg_array_index); + mailmh_msg_info_free(msg_info); + res = MAILMH_ERROR_MEMORY; + goto closedir; + } + //LR memory leak? added next line + //mailmh_msg_info_free(msg_info); + //it seems so that it should be freed later, + // but it is not in every case + //PENDING fixme in ompi somewhere + } + } + else if (S_ISDIR(buf.st_mode)) { + struct mailmh_folder * subfolder; + unsigned int array_index; + chashdatum key; + chashdatum data; + + if (ent->d_name[0] == '.') { + if (ent->d_name[1] == 0) + continue; + if ((ent->d_name[1] == '.') && (ent->d_name[2] == 0)) + continue; + } + + key.data = ent->d_name; + key.len = strlen(ent->d_name); + r = chash_get(folder->fl_subfolders_hash, &key, &data); + if (r < 0) { + subfolder = mailmh_folder_new(folder, ent->d_name); + if (subfolder == NULL) { + res = MAILMH_ERROR_MEMORY; + goto closedir; + } - r = carray_add(folder->fl_subfolders_tab, subfolder, &array_index); - if (r < 0) { - mailmh_folder_free(subfolder); - res = MAILMH_ERROR_MEMORY; - goto closedir; - } - subfolder->fl_array_index = array_index; + r = carray_add(folder->fl_subfolders_tab, subfolder, &array_index); + if (r < 0) { + mailmh_folder_free(subfolder); + res = MAILMH_ERROR_MEMORY; + goto closedir; + } + subfolder->fl_array_index = array_index; - key.data = subfolder->fl_filename; - key.len = strlen(subfolder->fl_filename); - data.data = subfolder; - data.len = 0; - r = chash_set(folder->fl_subfolders_hash, &key, &data, NULL); - if (r < 0) { - carray_delete_fast(folder->fl_subfolders_tab, subfolder->fl_array_index); - mailmh_folder_free(subfolder); - res = MAILMH_ERROR_MEMORY; - goto closedir; - } - } - } + key.data = subfolder->fl_filename; + key.len = strlen(subfolder->fl_filename); + data.data = subfolder; + data.len = 0; + r = chash_set(folder->fl_subfolders_hash, &key, &data, NULL); + if (r < 0) { + carray_delete_fast(folder->fl_subfolders_tab, subfolder->fl_array_index); + mailmh_folder_free(subfolder); + res = MAILMH_ERROR_MEMORY; + goto closedir; + } + } + } + } } - } - while (ent != NULL); + while (ent != NULL); - folder->fl_max_index = max_index; + folder->fl_max_index = max_index; - mh_seq = malloc(strlen(folder->fl_filename) + 2 + sizeof(".mh_sequences")); - if (mh_seq == NULL) { - res = MAILMH_ERROR_MEMORY; - goto closedir; - } - strcpy(mh_seq, folder->fl_filename); - strcat(mh_seq, MAIL_DIR_SEPARATOR_S); - strcat(mh_seq, ".mh_sequences"); + mh_seq = malloc(strlen(folder->fl_filename) + 2 + sizeof(".mh_sequences")); + if (mh_seq == NULL) { + res = MAILMH_ERROR_MEMORY; + goto closedir; + } + strcpy(mh_seq, folder->fl_filename); + strcat(mh_seq, MAIL_DIR_SEPARATOR_S); + strcat(mh_seq, ".mh_sequences"); - if (stat(mh_seq, &buf) == -1) { - int fd; + if (stat(mh_seq, &buf) == -1) { + int fd; - fd = creat(mh_seq, S_IRUSR | S_IWUSR); - if (fd != -1) - close(fd); - } - free(mh_seq); + fd = creat(mh_seq, S_IRUSR | S_IWUSR); + if (fd != -1) + close(fd); + } + free(mh_seq); - closedir(d); + closedir(d); - return MAILMH_NO_ERROR; + return MAILMH_NO_ERROR; closedir: - closedir(d); + closedir(d); err: - return res; + return res; } int mailmh_folder_add_subfolder(struct mailmh_folder * parent, - const char * name) + const char * name) { - char * foldername; - int r; - struct mailmh_folder * folder; - unsigned int array_index; - chashdatum key; - chashdatum data; + char * foldername; + int r; + struct mailmh_folder * folder; + unsigned int array_index; + chashdatum key; + chashdatum data; - foldername = malloc(strlen(parent->fl_filename) + strlen(name) + 2); - if (foldername == NULL) - return MAILMH_ERROR_MEMORY; - strcpy(foldername, parent->fl_filename); - strcat(foldername, MAIL_DIR_SEPARATOR_S); - strcat(foldername, name); + foldername = malloc(strlen(parent->fl_filename) + strlen(name) + 2); + if (foldername == NULL) + return MAILMH_ERROR_MEMORY; + strcpy(foldername, parent->fl_filename); + strcat(foldername, MAIL_DIR_SEPARATOR_S); + strcat(foldername, name); - r = mkdir(foldername, 0700); - free(foldername); + r = mkdir(foldername, 0700); + free(foldername); - if (r < 0) - return MAILMH_ERROR_FOLDER; + if (r < 0) + return MAILMH_ERROR_FOLDER; - folder = mailmh_folder_new(parent, name); - if (folder == NULL) - return MAILMH_ERROR_MEMORY; + folder = mailmh_folder_new(parent, name); + if (folder == NULL) + return MAILMH_ERROR_MEMORY; - r = carray_add(parent->fl_subfolders_tab, folder, &array_index); - if (r < 0) { - mailmh_folder_free(folder); - return MAILMH_ERROR_MEMORY; - } - folder->fl_array_index = array_index; - - key.data = folder->fl_filename; - key.len = strlen(folder->fl_filename); - data.data = folder; - data.len = 0; - - r = chash_set(parent->fl_subfolders_hash, &key, &data, NULL); - if (r < 0) { - carray_delete_fast(folder->fl_subfolders_tab, folder->fl_array_index); - mailmh_folder_free(folder); - return MAILMH_ERROR_MEMORY; - } + r = carray_add(parent->fl_subfolders_tab, folder, &array_index); + if (r < 0) { + mailmh_folder_free(folder); + return MAILMH_ERROR_MEMORY; + } + folder->fl_array_index = array_index; + + key.data = folder->fl_filename; + key.len = strlen(folder->fl_filename); + data.data = folder; + data.len = 0; + + r = chash_set(parent->fl_subfolders_hash, &key, &data, NULL); + if (r < 0) { + carray_delete_fast(folder->fl_subfolders_tab, folder->fl_array_index); + mailmh_folder_free(folder); + return MAILMH_ERROR_MEMORY; + } - return MAILMH_NO_ERROR; + return MAILMH_NO_ERROR; } int mailmh_folder_remove_subfolder(struct mailmh_folder * folder) { - struct mailmh_folder * parent; - chashdatum key; - chashdatum data; - int r; + struct mailmh_folder * parent; + chashdatum key; + chashdatum data; + int r; - parent = folder->fl_parent; + parent = folder->fl_parent; - key.data = folder->fl_filename; - key.len = strlen(folder->fl_filename); + key.data = folder->fl_filename; + key.len = strlen(folder->fl_filename); - r = chash_get(parent->fl_subfolders_hash, &key, &data); - if (r < 0) - return MAILMH_ERROR_FOLDER; + r = chash_get(parent->fl_subfolders_hash, &key, &data); + if (r < 0) + return MAILMH_ERROR_FOLDER; - chash_delete(parent->fl_subfolders_hash, &key, NULL); - carray_delete_fast(parent->fl_subfolders_tab, folder->fl_array_index); + chash_delete(parent->fl_subfolders_hash, &key, NULL); + carray_delete_fast(parent->fl_subfolders_tab, folder->fl_array_index); - mailmh_folder_free(folder); + mailmh_folder_free(folder); - return MAILMH_NO_ERROR; + return MAILMH_NO_ERROR; } int mailmh_folder_rename_subfolder(struct mailmh_folder * src_folder, - struct mailmh_folder * dst_folder, - const char * new_name) + struct mailmh_folder * dst_folder, + const char * new_name) { - int r; - struct mailmh_folder * folder; - struct mailmh_folder * parent; - char * new_foldername; + int r; + struct mailmh_folder * folder; + struct mailmh_folder * parent; + char * new_foldername; - parent = src_folder->fl_parent; - if (parent == NULL) - return MAILMH_ERROR_RENAME; + parent = src_folder->fl_parent; + if (parent == NULL) + return MAILMH_ERROR_RENAME; - new_foldername = malloc(strlen(dst_folder->fl_filename) + 2 + strlen(new_name)); - if (new_foldername == NULL) - return MAILMH_ERROR_MEMORY; + new_foldername = malloc(strlen(dst_folder->fl_filename) + 2 + strlen(new_name)); + if (new_foldername == NULL) + return MAILMH_ERROR_MEMORY; - strcpy(new_foldername, dst_folder->fl_filename); - strcat(new_foldername, MAIL_DIR_SEPARATOR_S); - strcat(new_foldername, new_name); + strcpy(new_foldername, dst_folder->fl_filename); + strcat(new_foldername, MAIL_DIR_SEPARATOR_S); + strcat(new_foldername, new_name); - r = rename(src_folder->fl_filename, new_foldername); - free(new_foldername); - if (r < 0) - return MAILMH_ERROR_RENAME; + r = rename(src_folder->fl_filename, new_foldername); + free(new_foldername); + if (r < 0) + return MAILMH_ERROR_RENAME; - r = mailmh_folder_remove_subfolder(src_folder); - if (r != MAILMH_NO_ERROR) - return r; + r = mailmh_folder_remove_subfolder(src_folder); + if (r != MAILMH_NO_ERROR) + return r; - folder = mailmh_folder_new(dst_folder, new_name); - if (folder == NULL) - return MAILMH_ERROR_MEMORY; + folder = mailmh_folder_new(dst_folder, new_name); + if (folder == NULL) + return MAILMH_ERROR_MEMORY; - r = carray_add(parent->fl_subfolders_tab, folder, NULL); - if (r < 0) { - mailmh_folder_free(folder); - return MAILMH_ERROR_MEMORY; - } + r = carray_add(parent->fl_subfolders_tab, folder, NULL); + if (r < 0) { + mailmh_folder_free(folder); + return MAILMH_ERROR_MEMORY; + } - return MAILMH_NO_ERROR; + return MAILMH_NO_ERROR; } #define MAX_TRY_ALLOC 32 /* initial file MUST be in the same directory */ static int mailmh_folder_alloc_msg(struct mailmh_folder * folder, char * filename, uint32_t * result) { uint32_t max; uint32_t k; char * new_filename; size_t len; struct stat f_stat; len = strlen(folder->fl_filename) + 20; new_filename = malloc(len); if (new_filename == NULL) return MAILMH_ERROR_MEMORY; max = folder->fl_max_index + 1; //fprintf(stderr,"mailmh_folder_alloc_msg filename: %s \n", filename); k = 0; while (k < MAX_TRY_ALLOC) { snprintf(new_filename, len, "%s%c%lu", folder->fl_filename, MAIL_DIR_SEPARATOR, (unsigned long) (max + k)); //fprintf(stderr,"mailmh_folder_alloc_msg new_filename: %s \n", new_filename); if ( stat( new_filename, &f_stat ) == -1 ) { // if (link(filename, new_filename) == 0) { int r; //fprintf(stderr,"filename found \n"); //unlink(filename); rename (filename,new_filename ); free(new_filename); if (k > MAX_TRY_ALLOC / 2) { r = mailmh_folder_update(folder); /* ignore errors */ } * result = max + k; folder->fl_max_index = max + k; return MAILMH_NO_ERROR; } else if (errno == EXDEV) { |