363 lines
8.5 KiB
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;
|
|
}
|