home *** CD-ROM | disk | FTP | other *** search
- /*
- * (c) Copyright 1990, Kim Fabricius Storm. All rights reserved.
- *
- * Folder handling
- */
-
- /*#include <errno.h>*/
- #include "config.h"
- #include "articles.h"
- #include "news.h"
- #include "term.h"
- #include "menu.h"
-
- export int dont_sort_folders = 0;
- export char *folder_directory = NULL;
-
- /*
- * file name completion and expansion
- *
- * expand_mode bits:
- * 1: expand path names
- * 2: don't expand $N
- * 4: don't expand any $? (but $(...) is expanded)
- * 8: don't complain about ~... (shell will do that)
- */
-
-
- expand_file_name(dest, src, expand_mode)
- char *dest, *src;
- int expand_mode;
- {
- register char *cp, *dp, c;
- int parse, remap;
- char *cur_grp, *cur_art;
- import char *home_directory;
-
- cur_grp = current_group ? current_group->group_name : NULL;
- cur_art = (group_file_name && *group_file_name) ? group_path_name : NULL;
-
- for (dp = dest, parse = 1; c = *src; src++) {
-
- if (parse) {
-
- if ((expand_mode & 1) && c == '+') {
- if (folder_directory == NULL) {
- if (!(cp = getenv("FOLDER")))
- cp = FOLDER_DIRECTORY;
- folder_directory = home_relative(cp);
- }
-
- cp = folder_directory;
- goto cp_str;
- }
-
- if ((expand_mode & 1) && c == '~') {
- if (src[1] != '/') {
- if (expand_mode & 8) goto copy;
- msg("Can't handle ~user expansion (yet)");
- return 0;
- }
-
- cp = home_directory;
-
- cp_str:
- while (*cp) *dp++ = *cp++;
- if (dp[-1] != '/') *dp++ = '/';
- goto no_parse;
- }
-
- if ((expand_mode & 4) == 0 &&
- cur_art && c == '%' && (src[1] == ' ' || src[1] == NUL)) {
- cp = cur_art;
- while (*cp) *dp++ = *cp++;
- goto no_parse;
- }
-
- }
-
- if (c == '$' && src[1] == '(') {
- char envar[64];
- for (src += 2, cp = envar; (c = *src) != NUL && c != ')'; src++)
- *cp++ = c;
- *cp = NUL;
- if (cp != envar) {
- if ((cp = getenv(envar)) != NULL)
- while (*cp) *dp++ = *cp++;
- else {
- msg("Environment variable $(%d) not set", envar);
- return 0;
- }
- }
- goto no_parse;
- }
-
- if ((expand_mode & 4) == 0 && c == '$' && !isalnum(src[2])) {
- remap = 0;
- cp = NULL;
-
- switch (src[1]) {
- case 'A':
- cp = cur_art;
- break;
- case 'F':
- cp = cur_grp;
- remap = 1;
- break;
- case 'G':
- cp = cur_grp;
- break;
- case 'L':
- if (cp = strrchr(cur_grp, '.'))
- cp++;
- else
- cp = cur_grp;
- break;
- case 'N':
- if (expand_mode & 2) goto copy;
- if (cur_art) cp = group_file_name;
- if (cp == NULL) goto copy;
- break;
- default:
- goto copy;
- }
- src++;
-
- if (!cp) {
- msg("$%c not defined on this level", c);
- return 0;
- }
-
- while (*cp)
- if (remap && *cp == '.')
- cp++, *dp++ = '/';
- else
- *dp++ = *cp++;
- goto no_parse;
- }
-
- if (c == '/')
- if (dp != dest && dp[-1] == '/') goto no_parse;
-
- copy:
- *dp++ = c;
- parse = isspace(c);
- continue;
-
- no_parse:
- parse = 0;
- }
-
- *dp = NUL;
-
- return 1;
- }
-
-
- file_completion(path, index)
- char *path;
- int index;
- {
- static dir_in_use = 0;
- static char *head, *tail = NULL;
- static int tail_offset;
-
- char nbuf[FILENAME], buffer[FILENAME];
- char *dir, *base;
-
- if (path) {
- if (dir_in_use) {
- close_directory();
- dir_in_use = 0;
- }
-
- if (index < 0) return 0;
-
- head = path;
- tail = path + index;
- }
-
- if (!dir_in_use) {
- path = head;
- *tail = NUL;
-
- if (*path == '|') return -1; /* no completion for pipes */
-
- if (*path == '+' || *path == '~') {
- if (!expand_file_name(nbuf, path, 1))
- return 0; /* no completions */
- } else
- strcpy(nbuf, path);
-
- if (base = strrchr(nbuf, '/')) {
- if (base == nbuf) {
- dir = "/";
- base++;
- } else {
- *base++ = NUL;
- dir = nbuf;
- }
- } else {
- base = nbuf;
- dir = ".";
- }
-
- tail_offset = strlen(base);
-
- dir_in_use = list_directory(dir, base);
-
- return dir_in_use;
- }
-
- if (index)
- return compl_help_directory();
-
- if (!next_directory(buffer, 1)) return 0;
-
- strcpy(tail, buffer+tail_offset);
-
- return 1;
- }
-
-
- static int cancel_count;
-
- fcancel(ah)
- article_header *ah;
- {
- if (ah->attr == A_CANCEL) {
- cancel_count--;
- ah->flag = 0;
- } else {
- cancel_count++;
- ah->attr = A_CANCEL;
- }
- }
-
- static folder_header()
- {
- so_printxy(0, 0, "Folder: %s", current_group->group_name);
-
- return 1; /* number of header lines */
- }
-
- folder_menu(path)
- char *path;
- {
- FILE *folder;
- register article_header *ah;
- news_header_buffer dgbuf;
- char buffer[256];
- int more, length, re, menu_cmd, was_raw;
- memory_marker mem_marker;
- group_header fake_group;
- int cc_save;
- extern time_stamp pack_date();
-
- fake_group.group_name = path;
- fake_group.group_flag = G_FOLDER | G_FAKED;
- fake_group.master_flag = 0;
- fake_group.save_file = NULL;
- current_group = NULL;
- init_group(&fake_group);
-
- folder = open_file(path, OPEN_READ);
- if (folder == NULL) {
- msg("%s not found", path);
- return ME_NO_REDRAW;
- }
-
- was_raw = no_raw();
- s_keyboard = 0;
-
- printf("\rReading: %-.65s", path);
- clrline();
-
- current_group = &fake_group;
-
- mark_memory(&mem_marker);
-
- ah = alloc_art();
-
- more = 1;
- while (more && (more = get_digest_article(folder, dgbuf)) >= 0) {
- if (s_keyboard) break;
-
- ah->a_number = 0;
- ah->flag = A_FOLDER;
- ah->attr = 0;
-
- ah->lines = digest.dg_lines;
-
- ah->hpos = digest.dg_hpos;
- ah->fpos = digest.dg_fpos;
- ah->lpos = digest.dg_lpos;
-
- if (digest.dg_from) {
- length = pack_name(buffer, digest.dg_from, NAME_LENGTH);
- ah->sender = alloc_str(length);
- strcpy(ah->sender, buffer);
- ah->name_length = length;
- } else {
- ah->sender = "";
- ah->name_length = 0;
- }
-
- if (digest.dg_subj) {
- length = pack_subject(buffer, digest.dg_subj, &re, 255);
- ah->replies = re;
- ah->subject = alloc_str(length);
- strcpy(ah->subject, buffer);
- ah->subj_length = length;
- } else {
- ah->replies = 0;
- ah->subject = "";
- ah->subj_length = 0;
- }
-
- ah->t_stamp = digest.dg_date ? pack_date(digest.dg_date) : 0;
-
- add_article(ah);
- ah = alloc_art();
- }
-
- fclose(folder);
-
- if (was_raw) raw();
-
- if (s_keyboard) {
- menu_cmd = ME_NO_REDRAW;
- } else
- if (n_articles == 0) {
- msg("Not a folder (no article header)");
- menu_cmd = ME_NO_REDRAW;
- } else {
- strcpy(buffer, path);
- fake_group.group_name = buffer; /* save for later use */
-
- if (n_articles > 1) {
- clrdisp();
- prompt_line = 2;
- if (!dont_sort_folders) sort_articles(-1);
- }
-
- cc_save = cancel_count;
- cancel_count = 0;
-
- reenter_menu:
- menu_cmd = menu(folder_header);
-
- if (cancel_count) {
- clrdisp();
- printf("Folder: %s\nFile: %s\n\n", buffer, group_path_name);
- if (cancel_count == n_articles)
- printf("Cancel all articles and remove folder? ");
- else
- printf("Remove %d article%s from folder? ",
- cancel_count, plural((long)cancel_count));
- fl;
-
- switch (yes(1)) {
- case 1:
- printf("\n\n");
- if (cancel_count == n_articles) {
- if (unlink(group_path_name) < 0) {
- printf("Could not unlink %s\n", group_path_name);
- sleep(3);
- }
- } else
- rewrite_folder();
- break;
- case 0:
- break;
- default:
- goto reenter_menu;
- }
- }
- cancel_count = cc_save;
- }
-
- release_memory(&mem_marker);
-
- return menu_cmd;
- }
-
-
- rewrite_folder()
- {
- register FILE *src, *dst;
- char oldfile[FILENAME], *sp;
- register int c;
- register long cnt;
- register article_header *ah, **ahp;
- register article_number n;
-
- if ((src = fopen(group_path_name, "r")) == NULL) {
- msg("Cannot open %s", group_path_name);
- return;
- }
-
- strcpy(oldfile, group_path_name);
- sp = strrchr(oldfile, '/');
- strcpy((sp == NULL ? oldfile : sp+1), "~OLD~FOLDER~");
-
- unlink(oldfile);
- if (link(group_path_name, oldfile) < 0) goto move_error;
- if (unlink(group_path_name) < 0) {
- if (unlink(oldfile) == 0) goto move_error;
- printf("\n\n%s was linked to %s --- cannot proceed\n",
- group_path_name, oldfile);
- sleep(5);
- return;
- }
-
- if ((dst = fopen(group_path_name, "w")) == NULL) {
- fclose(src);
- goto move_back;
- }
-
- sort_articles(0);
-
- printf("Compressing folder..."); fl;
-
- for (ahp = articles, n = n_articles; --n >= 0; ahp++) {
- ah = *ahp;
- if (ah->attr == A_CANCEL) continue;
- fseek(src, ah->hpos, 0);
- cnt = ah->lpos - ah->hpos;
- while (--cnt >= 0) {
- if ((c = getc(src)) == EOF) break;
- putc(c, dst);
- }
- putc(NL, dst);
- }
- fclose(src);
- if (ferror(dst)) {
- fclose(dst);
- goto move_back;
- }
- return;
-
- move_back:
- if (link(oldfile, group_path_name) == 0) {
- unlink(oldfile);
- printf("Cannot create new file -- Folder restored\n");
- sleep(2);
- } else {
- printf("Cannot create new file\n\nFolder saved in %s\n",
- oldfile);
- sleep(10);
- }
- return;
-
- move_error:
- fclose(src);
- printf("\n\nCannot move folder %s to %s\n",
- group_path_name, oldfile);
- sleep(3);
- return;
- }
-