bitchx/source/queue.c

363 lines
8.5 KiB
C

/*
* queue.c - The queue command
*
* Queues allow for future batch processing
*
* Syntax: /QUEUE -DO -SHOW -LIST -NO_FLUSH -DELETE -FLUSH <name> {commands}
*
* Written by Jeremy Nelson (nelson@cs.uwp.edu) (ESL)
*
* Copyright (C) 1993. See the copyright file and all that rot
*/
#include "irc.h"
static char cvsrevision[] = "$Id$";
CVS_REVISION(queue_c)
#include "struct.h"
#include "alias.h"
#include "commands.h"
#include "ircaux.h"
#include "queue.h"
#include "output.h"
#define MAIN_SOURCE
#include "modval.h"
extern char *next_expr (char **, char);
struct CmdListT;
struct QueueT {
struct QueueT *next;
struct CmdListT *first;
char *name;
};
struct CmdListT {
struct CmdListT *next;
char *what;
};
typedef struct QueueT Queue;
typedef struct CmdListT CmdList;
static Queue *lookup_queue (Queue *, char *);
static int add_commands_to_queue (Queue *, char *, char *);
static void display_all_queues (Queue *);
static CmdList *walk_commands (Queue *);
static Queue *make_new_queue (Queue *, char *);
static int delete_commands_from_queue (Queue *, int);
static void flush_queue (Queue *);
static void print_queue (Queue *);
static int num_entries (Queue *);
static Queue *remove_a_queue (Queue *);
static Queue *do_queue (Queue *, int);
BUILT_IN_COMMAND(queuecmd)
{
Queue *tmp;
char *arg = NULL,
*name = NULL,
*startcmds = NULL,
*cmds = NULL;
int noflush = 0, runit = 0,
list = 0,
flush = 0, remove_by_number = 0,
commands = 1, number = 0;
static Queue *Queuelist;
/*
* If the queue list is empty, make an entry
* Some OS's barf on writing to static strings...
* I wish ultrix wasnt so darn forgiving...
*/
char this_sucks[4];
strcpy(this_sucks,"Top");
if (Queuelist == NULL)
Queuelist = make_new_queue(NULL, this_sucks);
if ((startcmds = strchr(args, '{')) == NULL)
commands = 0;
else
*(startcmds-1) = '\0';
while ((arg = upper(next_arg(args, &args))) != NULL)
{
if (*arg == '-' || *arg == '/')
{
*arg++ = '\0';
if (!strcmp(arg, "NO_FLUSH"))
noflush = 1;
else if (!strcmp(arg, "SHOW"))
{
display_all_queues(Queuelist);
return;
}
else if (!strcmp(arg, "LIST"))
list = 1;
else if (!strcmp(arg, "DO"))
runit = 1;
else if (!strcmp(arg, "DELETE"))
remove_by_number = 1;
else if (!strcmp(arg, "FLUSH"))
flush = 1;
}
else
{
if (name)
number = atoi(arg);
else
name = arg;
}
}
if (name == NULL)
return;
/* Find the queue based upon the previous queue */
tmp = lookup_queue(Queuelist, name);
/* if the next queue is empty, then we need to see if
we should make it or output an error */
if ((tmp->next) == NULL)
{
if (commands)
tmp->next = make_new_queue(NULL, name);
else
{
yell ("QUEUE: (%s) no such queue",name);
return;
}
}
if (remove_by_number == 1)
if (delete_commands_from_queue(tmp->next,number))
tmp->next = remove_a_queue(tmp->next);
if (list == 1)
print_queue(tmp->next);
if (runit == 1)
tmp->next = do_queue(tmp->next, noflush);
if (flush == 1)
tmp->next = remove_a_queue(tmp->next);
if (startcmds)
{
int booya;
if ((cmds = next_expr(&startcmds, '{')) == NULL)
{
yell ("QUEUE: missing closing brace");
return;
}
booya = add_commands_to_queue (tmp->next, cmds, subargs);
say ("QUEUED: %s now has %d entries",name, booya);
}
}
/*
* returns the queue BEFORE the queue we are looking for
* returns the last queue if no match
*/
static Queue * lookup_queue (Queue *queue, char *what)
{
Queue *tmp = queue;
upper(what);
while (tmp->next)
{
if (!strcmp(tmp->next->name, what))
return tmp;
else
if (tmp->next)
tmp = tmp->next;
else
break;
}
return tmp;
}
/* returns the last CmdList in a queue, useful for appending commands */
static CmdList *walk_commands (Queue *queue)
{
CmdList *ctmp = queue->first;
if (ctmp)
{
while (ctmp->next)
ctmp = ctmp->next;
return ctmp;
}
return NULL;
}
/*----------------------------------------------------------------*/
/* Make a new queue, link it in, and return it. */
static Queue *make_new_queue (Queue *afterqueue, char *name)
{
Queue *tmp = (Queue *)new_malloc(sizeof(Queue));
upper(name);
tmp->next = afterqueue;
tmp->first = NULL;
tmp->name = NULL;
malloc_strcpy(&tmp->name, name);
return tmp;
}
/* add a command to a queue, at the end of the list */
/* expands the whole thing once and stores it */
static int add_commands_to_queue (Queue *queue, char *what, char *subargs)
{
CmdList *ctmp = walk_commands(queue);
char *list = NULL,
*sa;
int args_flag = 0;
sa = subargs ? subargs : space;
list = expand_alias(what,sa,&args_flag, NULL);
if (!ctmp)
{
queue->first = (CmdList *)new_malloc(sizeof(CmdList));
ctmp = queue->first;
}
else
{
ctmp->next = (CmdList *)new_malloc(sizeof(CmdList));
ctmp = ctmp->next;
}
ctmp->what = NULL;
malloc_strcpy(&ctmp->what, list);
ctmp->next = NULL;
new_free(&list);
return num_entries(queue);
}
/* remove the Xth command from the queue */
static int delete_commands_from_queue (Queue *queue, int which)
{
CmdList *ctmp = queue->first;
CmdList *blah;
int x;
if (which == 1)
queue->first = ctmp->next;
else
{
for (x=1;x<which-1;x++)
{
if (ctmp->next)
ctmp = ctmp->next;
else
return 0;
}
blah = ctmp->next;
ctmp->next = ctmp->next->next;
ctmp = blah;
}
new_free(&ctmp->what);
new_free((char **)&ctmp);
if (queue->first == NULL)
return 1;
else
return 0;
}
/*-------------------------------------------------------------------*/
/* flush a queue, deallocate the memory, and return the next in line */
static Queue *remove_a_queue (Queue *queue)
{
Queue *next = queue->next;
flush_queue(queue);
new_free(&queue->name);
new_free(&queue);
return next;
}
/* walk through a queue, deallocating the entries */
static void flush_queue (Queue *queue)
{
CmdList *cmd_list = queue->first;
while (cmd_list != NULL)
{
CmdList *next = cmd_list->next;
new_free(&cmd_list->what);
new_free(&cmd_list);
cmd_list = next;
}
queue->first = NULL;
}
/*------------------------------------------------------------------------*/
/* run the queue, and if noflush, then return the queue, else return the
next queue */
static Queue *do_queue (Queue *queue, int noflush)
{
CmdList *tmp;
tmp = queue->first;
do
{
if (tmp->what != NULL)
parse_line("QUEUE", tmp->what, empty_string, 0, 0, 1);
tmp = tmp->next;
}
while (tmp != NULL);
if (!noflush)
return remove_a_queue(queue);
else
return queue;
}
/* ---------------------------------------------------------------------- */
/* output the contents of all the queues to the screen */
static void display_all_queues (Queue *queue)
{
Queue *tmp = queue->next;
while (tmp)
{
print_queue(tmp);
if (tmp->next == NULL)
return;
else
tmp = tmp->next;
}
yell("QUEUE: No more queues");
}
/* output the contents of a queue to the screen */
static void print_queue (Queue *queue)
{
CmdList *tmp;
int x = 0;
tmp = queue->first;
while (tmp != NULL)
{
if (tmp->what)
say ("<%s:%2d> %s",queue->name,++x,tmp->what);
tmp = tmp->next;
}
say ("<%s> End of queue",queue->name);
}
/* return the number of entries in a queue */
static int num_entries (Queue *queue)
{
int x = 1;
CmdList *tmp;
if ((tmp = queue->first) == NULL)
return 0;
while (tmp->next)
{
x++;
tmp = tmp->next;
}
return x;
}