Initial import of the ircii-pana-1.1-final source tree.
git-svn-id: svn://svn.code.sf.net/p/bitchx/code/tags/ircii-pana-1.1-final@1 13b04d17-f746-0410-82c6-800466cd88b0
This commit is contained in:
363
source/queue.c
Normal file
363
source/queue.c
Normal file
@@ -0,0 +1,363 @@
|
||||
/*
|
||||
* 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: queue.c,v 1.1.1.1 2003/04/11 01:09:07 dan Exp $";
|
||||
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 *tmp;
|
||||
tmp = queue->next;
|
||||
flush_queue(queue);
|
||||
new_free((char **)&queue);
|
||||
return tmp;
|
||||
}
|
||||
|
||||
/* walk through a queue, deallocating the entries */
|
||||
static void flush_queue (Queue *queue)
|
||||
{
|
||||
CmdList *tmp, *tmp2;
|
||||
tmp = queue->first;
|
||||
|
||||
while (tmp != NULL)
|
||||
{
|
||||
tmp2 = tmp;
|
||||
tmp = tmp2->next;
|
||||
if (tmp2->what != NULL)
|
||||
new_free(&tmp2->what);
|
||||
if (tmp2)
|
||||
new_free((char **)&tmp2);
|
||||
}
|
||||
}
|
||||
|
||||
/*------------------------------------------------------------------------*/
|
||||
/* 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;
|
||||
}
|
||||
Reference in New Issue
Block a user