home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Usenet 1994 October
/
usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso
/
misc
/
volume30
/
tin
/
part13
/
active.c
next >
Wrap
C/C++ Source or Header
|
1992-05-20
|
9KB
|
385 lines
/*
* Project : tin - a threaded Netnews reader
* Module : active.c
* Author : I.Lea
* Created : 16-02-92
* Updated : 02-05-92
* Notes :
* Copyright : (c) Copyright 1991-92 by Iain Lea
* You may freely copy or redistribute this software,
* so long as there is no profit made from its use, sale
* trade or reproduction. You may not change this copy-
* right notice, and it must be included in any copy made
*/
#include "tin.h"
int group_hash[TABLE_SIZE]; /* group name --> active[] */
int reread_active_file = FALSE;
/*
* Resync active file when SIGALRM signal received that
* is triggered by alarm (RESYNC_ACTIVE_SECS) call.
*/
void resync_active_file ()
{
if (reread_active_file) {
free_active_arrays ();
max_active = DEFAULT_ACTIVE_NUM;
expand_active ();
read_active_file ();
read_newsrc (TRUE);
set_alarm_signal ();
group_selection_page ();
}
}
/*
* Load the active file into active[] and create copy of active ~/.tin/active
*/
int read_active_file ()
{
FILE *fp;
char *p, *q, *r;
char buf[LEN];
char moderated = 'y';
int created, i;
long h;
num_active = 0;
if (! update) {
wait_message (txt_reading_active_file);
}
if ((fp = open_active_fp ()) == NULL) {
if (compiled_with_nntp) {
sprintf (msg, txt_cannot_open_active_file, active_file, progname);
wait_message (msg);
} else {
fputc ('\n', stderr);
fprintf (stderr, txt_cannot_open, active_file);
fputc ('\n', stderr);
fflush (stderr);
}
exit (1);
}
for (i = 0; i < TABLE_SIZE; i++) {
group_hash[i] = -1;
}
while (fgets (buf, sizeof (buf), fp) != NULL) {
for (p = buf; *p && *p != ' '; p++)
continue;
if (*p != ' ') {
error_message (txt_bad_active_file, buf);
continue;
}
*p++ = '\0';
if (num_active >= max_active) {
debug_nntp ("read_active_file", "EXPANDING active file");
expand_active ();
}
h = hash_groupname (buf);
if (group_hash[h] == -1) {
group_hash[h] = num_active;
} else { /* hash linked list chaining */
for (i=group_hash[h]; active[i].next >= 0; i=active[i].next) {
if (strcmp(active[i].name, buf) == 0) {
goto read_active_continue; /* kill dups */
}
}
if (strcmp(active[i].name, buf) == 0)
goto read_active_continue;
active[i].next = num_active;
}
for (q = p; *q && *q != ' '; q++)
continue;
if (*q != ' ') {
error_message (txt_bad_active_file, buf);
continue;
}
*q++ = '\0';
for (r = q; *r && *r != '\n'; r++) {
if (*r == 'y' || *r == 'm') {
moderated = *r;
break;
}
}
/*
* Group info.
*/
active[num_active].name = str_dup (buf);
active[num_active].max = (long) atol (p);
active[num_active].min = (long) atol (q);
active[num_active].moderated = moderated;
active[num_active].next = -1; /* hash chaining */
active[num_active].flag = UNSUBSCRIBED; /* not in my_group[] yet */
/*
* Per group attributes
*/
active[num_active].attribute.server = (char *) 0;
active[num_active].attribute.maildir = default_maildir;
active[num_active].attribute.savedir = default_savedir;
active[num_active].attribute.sigfile = default_sigfile;
active[num_active].attribute.read = FALSE; /* read/unread */
active[num_active].attribute.showall = show_only_unread;
active[num_active].attribute.thread = thread_arts;
active[num_active].attribute.sortby = sort_art_type;
active[num_active].attribute.author = show_author;
active[num_active].attribute.autosave= save_archive_name;
active[num_active].attribute.process = post_proc_type;
num_active++;
read_active_continue:;
}
fclose (fp);
/*
* exit if active file is empty
*/
if (! num_active) {
error_message (txt_active_file_is_empty, active_file);
exit (1);
}
/*
* create backup of LIBDIR/active for use by -n option to notify new groups
*/
created = backup_active (TRUE);
debug_print_active ();
if (cmd_line && (read_news_via_nntp && update == FALSE)) {
if (! (update && ! verbose)) {
wait_message ("\n");
}
}
return (created);
}
/*
* create ~/.tin/active from LIBDIR/active if it does not exist
*/
int backup_active (create)
int create;
{
char buf[LEN];
FILE *fp;
int created = FALSE;
int i;
struct stat sb;
sprintf (buf, "%s/active", rcdir);
if (create) {
if (stat (buf, &sb) != -1) {
goto backup_active_done;
}
}
if ((fp = fopen (buf, "w")) != NULL) {
for (i = 0; i < num_active ; i++) { /* for each group */
fprintf (fp, "%s\n", active[i].name);
}
fclose (fp);
chmod (buf, 0644);
created = TRUE;
}
backup_active_done:
return (created);
}
/*
* Option -n to check for any newly created newsgroups.
*/
void notify_groups ()
{
char buf[LEN];
FILE *fp;
int group_not_found;
int index;
int num = 0;
int update_old_active = FALSE;
int max_old_active;
register int i, j;
struct notify_t {
char name[LEN];
int len;
int visited;
} *old_active = (struct notify_t *) 0;
sprintf (buf, "%s/active", rcdir);
if ((fp = fopen (buf, "r")) == NULL) {
perror_message (txt_cannot_open, buf);
goto notify_groups_done;
}
Raw (TRUE);
wait_message (txt_checking_active_file);
max_old_active = num_active;
old_active = (struct notify_t *) my_malloc ((unsigned) sizeof (struct notify_t) * max_old_active);
if (old_active == (struct notify_t *) 0) {
error_message (txt_out_of_memory, progname);
goto notify_groups_done;
}
while (fgets (old_active[num].name, sizeof (old_active[num].name), fp) != NULL) {
old_active[num].len = strlen (old_active[num].name)-1;
old_active[num].name[old_active[num].len] = '\0';
old_active[num].visited = FALSE;
num++;
if (num >= max_old_active) {
max_old_active= max_old_active + (max_old_active / 2);
old_active= (struct notify_t*) my_realloc(
(char *) old_active,
(unsigned) sizeof(struct notify_t) * max_old_active);
if (old_active == (struct notify_t *) 0) {
error_message (txt_out_of_memory, progname);
goto notify_groups_done;
}
}
}
for (i = 0 ; i < num_active ; i++) {
group_not_found = TRUE;
for (j=0; j < num ; j++) {
if (strcmp (old_active[j].name, active[i].name) == 0) {
group_not_found = FALSE; /* found it so read in next group */
old_active[j].visited = TRUE;
break;
}
}
if (group_not_found == FALSE) {
continue;
}
update_old_active = TRUE;
do {
fputc ('\r', stdout);
CleartoEOLN();
printf (txt_subscribe_to_new_group, active[i].name);
fflush (stdout);
buf[0] = ReadCh();
} while (buf[0] != 'y' && buf[0] != 'n');
if (buf[0] == 'y') {
index = add_group (active[i].name, TRUE);
subscribe (active[my_group[index]].name, ':',
my_group[index], FALSE);
}
printf ("\r\n%s", txt_checking);
fflush (stdout);
}
fclose (fp);
fputc ('\r', stdout);
fflush (stdout);
CleartoEOLN();
/*
* Look for bogus groups
*/
for (j = 0 ; j < num ; j++) {
if (old_active[j].visited) {
continue;
}
do {
update_old_active= 1;
fputc ('\r', stdout);
CleartoEOLN ();
printf (txt_delete_bogus_group, old_active[j].name);
fflush (stdout);
buf[0] = ReadCh ();
} while (buf[0] != 'y' && buf[0] != 'n');
if (buf[0] == 'y') {
delete_group (old_active[j].name);
}
printf ("\r\n");
}
Raw (TRUE);
/*
* write active[] to ~/.tin/active
*/
if (update_old_active) {
backup_active (FALSE);
}
notify_groups_done:
if (old_active != (struct notify_t *) 0) {
free ((char *) old_active);
old_active = (struct notify_t *) 0;
}
}
/*
* Mark any groups in my_group[] that are in ~/.tin/unthread so they
* will not be threaded
*/
void mark_unthreaded_groups ()
{
FILE *fp;
char buf[LEN];
int i, len;
long h;
#ifndef INDEX_DAEMON
if ((fp = fopen (unthreadfile, "r")) == NULL) {
perror_message (txt_cannot_open, unthreadfile);
return;
}
while (fgets (buf, sizeof (buf), fp) != NULL) {
buf[strlen (buf)-1] = '\0';
h = hash_groupname (buf);
sprintf (msg, "Unthreading %s...\n", buf);
wait_message (msg);
i = group_hash[h];
if (active[i].next == -1) {
len = strlen (active[i].name);
if (strncmp (active[i].name, buf, len) == 0) {
active[i].attribute.thread = FALSE;
}
} else {
for (i=group_hash[h]; active[i].next >= 0; i=active[i].next) {
len = strlen (active[i].name);
if (strncmp (active[i].name, buf, len) == 0) {
active[i].attribute.thread = FALSE;
break;
}
}
}
}
fclose (fp);
#endif /* INDEX_DAEMON */
}