Initial revision

This commit is contained in:
William Ferrell
1999-12-09 23:15:14 +00:00
commit 2635c3085d
139 changed files with 24298 additions and 0 deletions
+728
View File
@@ -0,0 +1,728 @@
#include <stdlib.h>
#include <stdio.h>
#include "LL.h"
#ifdef DEBUG
#undef DEBUG
#endif
//TODO: Comment everything
//TODO: Test everything?
//////////////////////////////////////////////////////////////////////
// Creates a new list...
LL * LL_new()
{
LL *list;
list = malloc(sizeof(LL));
if(!list) return NULL;
list->head.data=NULL;
list->head.prev=NULL;
list->head.next=&list->tail;
list->tail.data=NULL;
list->tail.prev=&list->head;
list->tail.next=NULL;
list->current = &list->head;
return list;
}
//////////////////////////////////////////////////////////////////////
// TODO: test this function
// Destroys the entire list
// Warning! Does not free the list data! (only the list itself)
int LL_Destroy(LL *list)
{
LL_node *node, *next;
if(!list) return -1;
node = &list->head;
for(node = node->next; node && node->next; node = next)
{
// Avoid accessing "node" after it's freed.. :)
next = node->next;
if(LL_node_Destroy(node) < 0) return -1;
}
free(list);
return 0;
}
//////////////////////////////////////////////////////////////////////
// TODO: test this function
// Warning! This does not assert that the node data is free!
int LL_node_Destroy(LL_node *node)
{
if(!node) return -1;
if(LL_node_Unlink(node) < 0) return -1;
free(node);
return 0;
}
//////////////////////////////////////////////////////////////////////
int LL_node_Unlink(LL_node *node)
{
LL_node *next, *prev;
if(!node) return -1;
next = node->next;
prev = node->prev;
if(next)
next->prev = prev;
if(prev)
prev->next = next;
node->next = NULL;
node->prev = NULL;
return 0;
}
//////////////////////////////////////////////////////////////////////
// Frees the data in a list node, if not NULL...
int LL_node_DestroyData(LL_node *node)
{
if(!node) return -1;
if(node->data) free(node->data);
else return -1;
return 0;
}
//////////////////////////////////////////////////////////////////////
// Returns to the beginning of the list...
int LL_Rewind(LL *list)
{
if(!list) return -1;
/*
printf("LL_Rewind: list=%8x\n", list);
printf("LL_Rewind: list.head=%8x\n", &list->head);
printf("LL_Rewind: list.tail=%8x\n", &list->tail);
*/
if(list->head.next != &list->tail)
list->current = list->head.next;
else
list->current = &list->head;
return 0;
}
//////////////////////////////////////////////////////////////////////
// Goes to the end of the list...
int LL_End(LL *list)
{
if(!list) return -1;
if(list->tail.prev != &list->head)
list->current = list->tail.prev;
else
list->current = &list->tail;
return 0;
}
//////////////////////////////////////////////////////////////////////
// Go to the next node
int LL_Next(LL *list)
{
if(!list) return -1;
if(!list->current) return -1;
if(list->current->next != &list->tail)
{
list->current = list->current->next;
return 0;
}
else
{
return -1;
}
}
//////////////////////////////////////////////////////////////////////
// Go to the previous node
int LL_Prev(LL *list)
{
if(!list) return -1;
if(!list->current) return -1;
if(list->current->prev != &list->head)
{
list->current = list->current->prev;
return 0;
}
else
{
return -1;
}
}
//////////////////////////////////////////////////////////////////////
// Data manipulation
void * LL_Get(LL *list)
{
if(!list) return NULL;
if(!list->current) return NULL;
return list->current->data;
}
//////////////////////////////////////////////////////////////////////
int LL_Put(LL *list, void *data)
{
if(!list) return -1;
if(!list->current) return -1;
list->current->data = data;
return 0;
}
//////////////////////////////////////////////////////////////////////
LL_node * LL_GetNode(LL *list)
{
if(!list) return NULL;
return list->current;
}
//////////////////////////////////////////////////////////////////////
// Don't use this unless you know what you're doing.
int LL_PutNode(LL *list, LL_node *node)
{
if(!list) return -1;
if(!node) return -1;
list->current = node;
return 0;
}
//////////////////////////////////////////////////////////////////////
void * LL_GetFirst(LL *list) // gets data from first node
{
if(!list) return NULL;
if(0> LL_Rewind(list)) return NULL;
return LL_Get(list);
}
//////////////////////////////////////////////////////////////////////
//
void * LL_GetNext (LL *list) // ... next node
{
if(!list) return NULL;
if(0 > LL_Next(list)) return NULL;
return LL_Get(list);
}
//////////////////////////////////////////////////////////////////////
void * LL_GetPrev (LL *list) // ... prev node
{
if(!list) return NULL;
if(0 > LL_Prev(list)) return NULL;
return LL_Get(list);
}
//////////////////////////////////////////////////////////////////////
void * LL_GetLast (LL *list) // ... last node
{
if(!list) return NULL;
if(0 > LL_End(list)) return NULL;
return LL_Get(list);
}
//////////////////////////////////////////////////////////////////////
int LL_AddNode(LL *list, void * add) // Adds node AFTER current one
{
LL_node *node;
if(!list) return -1;
//if(!add) return -1; // Nevermind.. NULL entries can be good...
if(!list->current) return -1;
//LL_dprint(list);
node = malloc(sizeof(LL_node));
if(!node) return -1;
//printf("Allocated node\n");
/* printf("Current: prev: %8x\tnode: %8x\tnext: %8x\n", */
/* (int)list->current->prev, */
/* (int)list->current, */
/* (int)list->current->next); */
if(list->current == &list->tail)
{
list->current = list->current->prev;
/* printf("Was at end of list...\n"); */
/* printf("Current: prev: %8x\tnode: %8x\tnext: %8x\n", */
/* (int)list->current->prev, */
/* (int)list->current, */
/* (int)list->current->next); */
}
// printf("Setting node data\n");
node->next = list->current->next;
node->prev = list->current;
node->data = add;
// printf("...done\n");
/* printf("NewNode: prev: %8x\tnode: %8x\tnext: %8x\n", */
/* (int)node->prev, */
/* (int)node, */
/* (int)node->next); */
// printf("Relinking...\n");
if(node->next)
node->next->prev = node;
// printf("...\n");
list->current->next = node;
// printf("...done\n");
list->current = node;
// printf("Added node\n");
// LL_dprint(list);
return 0;
}
//////////////////////////////////////////////////////////////////////
int LL_InsertNode(LL *list, void * add)// Adds node BEFORE current one
{
LL_node *node;
if(!list) return -1;
if(!add) return -1;
if(!list->current) return -1;
node = malloc(sizeof(LL_node));
if(!node) return -1;
if(list->current == &list->head) list->current = list->current->next;
node->next = list->current;
node->prev = list->current->prev;
node->data = add;
if(list->current->prev)
list->current->prev->next = node;
list->current->prev = node;
list->current = node;
return 0;
}
////////////////////////////////////////////////////////////////////////
// Removes a node from the link
// ... and advances one node forward
void * LL_DeleteNode(LL *list)
{
LL_node *next, *prev;
void *data;
if(!list) return NULL;
if(!list->current) return NULL;
if(list->current == &list->head) return NULL;
if(list->current == &list->tail) return NULL;
#ifdef DEBUG
printf("LL_DeleteNode: Before...\n");
LL_dprint(list);
#endif
next = list->current->next;
prev = list->current->prev;
data = list->current->data;
if(prev)
prev->next = next;
if(next)
next->prev = prev;
list->current->prev = NULL;
list->current->next = NULL;
// This should not free things; the user should do it explicitly.
//if(list->current->data) free(list->current->data);
list->current->data = NULL;
free(list->current);
list->current = next;
#ifdef DEBUG
printf("LL_DeleteNode: After...\n");
LL_dprint(list);
#endif
return data;
}
//////////////////////////////////////////////////////////////////////
// Removes a specific node...
void * LL_Remove(LL *list, void * data)
{
void *find;
if(!list) return NULL;
LL_Rewind(list);
do {
find = LL_Get(list);
if(find == data) return LL_DeleteNode(list);
} while (LL_Next(list) == 0);
return NULL;
}
//////////////////////////////////////////////////////////////////////
// Stack operations
int LL_Push(LL *list, void *add) // Add node to end of list
{
if(!list) return -1;
if(!add) return -1;
// printf("Going to end of list...\n");
LL_End(list);
// printf("Adding node...\n");
return LL_AddNode(list, add);
}
//////////////////////////////////////////////////////////////////////
void * LL_Pop(LL *list) // Remove node from end of list
{
if(!list) return NULL;
if(0 > LL_End(list)) return NULL;
return LL_DeleteNode(list);
}
//////////////////////////////////////////////////////////////////////
void * LL_Top(LL *list) // Peek at end node
{
return LL_GetLast(list);
}
//////////////////////////////////////////////////////////////////////
void * LL_Shift(LL *list) // Remove node from start of list
{
if(!list) return NULL;
if(0 > LL_Rewind(list)) return NULL;
return LL_DeleteNode(list);
}
//////////////////////////////////////////////////////////////////////
void * LL_Look(LL *list) // Peek at first node
{
return LL_GetFirst(list);
}
//////////////////////////////////////////////////////////////////////
int LL_Unshift(LL *list, void *add) // Add node to beginning of list
{
if(!list) return -1;
if(!add) return -1;
LL_Rewind(list);
return LL_InsertNode(list, add);
}
//////////////////////////////////////////////////////////////////////
int LL_Roll(LL *list) // Make last node first
{
LL_node *node, *next;
if(!list) return -1;
//if(!list->current) return -1;
if(0 > LL_End(list)) return -1;
// Avoid rolling an empty list, or unlinking the head/tail...
if(list->current == &list->head) list->current = list->current->next;
if(list->current == &list->tail) list->current = list->current->prev;
// List is empty
if(list->current == &list->head) return 0;
// List has one item
if(list->current->prev == &list->head) return 0;
node = list->current;
LL_node_Unlink(node);
if(0 > LL_Rewind(list)) return -1;
next = list->head.next;
list->head.next = node;
next->prev = node;
node->prev = &list->head;
node->next = next;
return 0;
}
//////////////////////////////////////////////////////////////////////
int LL_UnRoll(LL *list)// Roll the other way...
{
LL_node *node, *prev;
if(!list) return -1;
//if(!list->current) return -1;
if(0 > LL_Rewind(list)) return -1;
// Avoid rolling an empty list, or unlinking the head/tail...
if(list->current == &list->tail) list->current = list->current->prev;
if(list->current == &list->head) list->current = list->current->next;
// List is empty
if(list->current == &list->tail) return 0;
// List has one item
if(list->current->next == &list->tail) return 0;
node = list->current;
LL_node_Unlink(node);
if(0 > LL_End(list)) return -1;
prev = list->tail.prev;
list->tail.prev = node;
prev->next = node;
node->next = &list->tail;
node->prev = prev;
return 0;
}
//////////////////////////////////////////////////////////////////////
// Add an item to the end of its "priority group"
// The list is assumed to be sorted already...
int LL_PriorityEnqueue(LL *list, void *add, int compare(void *, void *))
{
void *data;
int i;
if(!list) return -1;
if(!add) return -1;
if(!compare) return -1;
// From the end of the list, keep searching while we're "less than"
// the given nodes...
LL_End(list);
do {
data = LL_Get(list);
if(data)
{
i = compare(add, data);
if(i >= 0) // If we're in the right place, add it and exit
{
LL_AddNode(list, add);
return 0;
}
}
} while(LL_Prev(list) == 0);
// If we're less than *everything*, put it at the beginning
LL_Unshift(list, add);
return 0;
}
//////////////////////////////////////////////////////////////////////
int LL_SwapNodes(LL_node *one, LL_node *two) // Switch two nodes positions...
{
LL_node *firstprev, *firstnext;
LL_node *secondprev, *secondnext;
if(!one || !two) return -1;
if(one == two) return 0; // Do nothing
firstprev = one->prev; // Look up the nodes neighbors...
firstnext = one->next;
secondprev = two->prev;
secondnext = two->next;
if(firstprev != NULL) firstprev->next = two; // Swap the neighboring
if(firstnext != NULL) firstnext->prev = two; // nodes pointers...
if(secondprev != NULL) secondprev->next = one;
if(secondprev != NULL) secondnext->prev = one;
one->next = secondnext; // Swap the nodes pointers
one->prev = secondprev;
two->next = firstnext;
two->prev = firstprev;
if(firstnext == two) one->prev = two; // Fix things in case
if(firstprev == two) one->next = two; // they were next to
if(secondprev == one) two->next = one; // each other...
if(secondnext == one) two->prev = one;
return 0;
}
//////////////////////////////////////////////////////////////////////
int LL_nSwapNodes(int one, int two) // Switch two nodes positions...
{
return -1;
}
//////////////////////////////////////////////////////////////////////
int LL_Length(LL *list) // Returns # of nodes in entire list
{
LL_node *node;
int num = 0;
if(!list) return -1;
node = &list->head;
for(num = -1;
node != &list->tail;
num++)
node = node->next;
return num;
}
//////////////////////////////////////////////////////////////////////
// Searching...
// Goes to the list item which matches "value", and returns the
// data found there.
//
// The "compare" function should return 0 for a "match"
//
// Note that this does *not* rewind the list first! You should do
// it yourself if you want to start from the beginning!
void * LL_Find(LL *list, int compare(void *, void *), void *value)
{
void *data;
if(!list) return NULL;
if(!compare) return NULL;
if(!value) return NULL;
do{
data = LL_Get(list);
if( 0 == compare(data, value) ) return data;
} while(LL_Next(list) == 0);
return NULL;
}
//////////////////////////////////////////////////////////////////////
// Sorts the list, then rewinds it...
//
int LL_Sort(LL *list, int compare(void *, void *))
{
int i,j; // Junk / loop variables
int numnodes; // number of nodes in list
LL_node *best, *last; // best match and last node in the list
LL_node *current;
if(!list) return -1;
if(!compare) return -1;
numnodes = LL_Length(list); // get the number of nodes...
if(0 > LL_End(list)) return -1; // Find the last node.
last = LL_GetNode(list);
if(numnodes < 2) return 0;
for(i=numnodes-1; i>0; i--)
{
LL_Rewind(list); // get the first node again
best = last; // reset our "best" node
for(j=0; j<i; j++)
{
current = LL_GetNode(list);
// If we found a better match...
if(compare(current->data, best->data) > 0)
{
best = current; // keep track of the "best" match
}
LL_Next(list); // Go to the next node.
}
LL_SwapNodes(last, best); // Switch two nodes...
if(best) last = best->prev;
else return -1;
//last = LL_FindPrev(best); // And go backwards by one node.
}
//return LLFindFirst(current); // return pointer to the first node.
LL_Rewind(list);
return 0;
}
void LL_dprint(LL *list)
{
LL_node *current;
current = &list->head;
printf("Head: prev:\t0x%8x\taddr:\t0x%8x\tnext:\t0x%8x\n",
(int)list->head.prev,
(int)&list->head,
(int)list->head.next);
for(current = current->next;
current != &list->tail;
current = current->next)
{
printf("node: prev:\t0x%8x\taddr:\t0x%8x\tnext:\t0x%8x\n",
(int)current->prev,
(int)current,
(int)current->next);
}
printf("Tail: prev:\t0x%8x\taddr:\t0x%8x\tnext:\t0x%8x\n",
(int)list->tail.prev,
(int)&list->tail,
(int)list->tail.next);
}
+209
View File
@@ -0,0 +1,209 @@
#ifndef LL_H
#define LL_H
/***********************************************************************
Linked Lists! (Doubly-Linked Lists)
*******************************************************************
To create a list, do the following:
LL *list;
list = LL_new();
if(!list) handle_an_error();
The list can hold any type of data. You will need to typecast your
datatype to a "void *", though. So, to add something to the list,
the following would be a good way to start:
typedef struct my_data {
char string[16];
int number;
} my_data;
my_data *thingie;
for(something to something else)
{
thingie = malloc(sizeof(my_data));
LL_AddNode(list, (void *)thingie); // typecast it to a "void *"
}
For errors, the general convention is that "0" means success, and
a negative number means failure. Check LL.c to be sure, though.
*******************************************************************
To change the data, try this:
thingie = (my_data *)LL_Get(list); // typecast it back to "my_data"
thingie->number = another_number;
You don't need to "Put" the data back, but it doesn't hurt anything.
LL_Put(list, (void *)thingie);
However, if you want to point the node's data somewhere else, you'll
need to get the current data first, keep track of it, then set the data
to a new location:
my_data * old_thingie, new_thingie;
old_thingie = (my_data *)LL_Get(list);
LL_Put(list, (void *)new_thingie);
// Now, do something with old_thingie. (maybe, free it?)
Or, you could just delete the node entirely and then add a new one:
my_data * thingie;
thingie = (my_data *)LL_DeleteNode(list);
free(thingie);
thingie->number = 666;
LL_InsertNode(list, (void *)thingie);
*******************************************************************
To operate on each list item, try this:
LL_Rewind(list);
do {
my_data = (my_data *)LL_Get(list);
... do something to it ...
} while(LL_Next(list) == 0);
*******************************************************************
You can also treat the list like a stack, or a queue. Just use the
following functions:
LL_Push() // Regular stack stuff: add, remove, peek, rotate
LL_Pop()
LL_Top()
LL_Roll()
LL_Shift() // Other end of the stack (like in perl)
LL_Unshift()
LL_Look()
LL_UnRoll()
LL_Enqueue() // Standard queue operations
LL_Dequeue()
There are also other goodies, like sorting and searching.
*******************************************************************
Array-like operations will come later, to allow numerical indexing:
LL_nGet(list, 3);
LL_nSwap(list, 6, 13);
LL_nPut(list, -4, data); // Puts item at 4th place from the end..
More ideas for later:
LL_MoveNode(list, amount); // Slides a node to another spot in the list
-- LL_MoveNode(list, -1); // moves a node back one toward the head
... um, more?
*******************************************************************
That's about it, for now... Be sure to free the list when you're done!
***********************************************************************/
// See LL.c for more detailed descriptions of these functions.
typedef struct LL_node
{
struct LL_node *next, *prev;
void *data;
} LL_node;
typedef struct LL
{
LL_node head, tail;
LL_node *current;
} LL;
// Creates a new list...
LL * LL_new();
// Destroying lists...
int LL_Destroy(LL *list);
int LL_node_Destroy(LL_node *node);
int LL_node_Unlink(LL_node *node);
int LL_node_DestroyData(LL_node *node);
// Returns to the beginning of the list...
int LL_Rewind(LL *list);
// Goes to the end of the list...
int LL_End(LL *list);
// Go to the next node
int LL_Next(LL *list);
// Go to the previous node
int LL_Prev(LL *list);
// Data manipulation
void * LL_Get(LL *list);
int LL_Put(LL *list, void *data);
// Don't use these next two unless you really know what you're doing.
LL_node * LL_GetNode(LL *list);
int LL_PutNode(LL *list, LL_node *node);
void * LL_GetFirst(LL *list); // gets data from first node
void * LL_GetNext (LL *list); // ... next node
void * LL_GetPrev (LL *list); // ... prev node
void * LL_GetLast (LL *list); // ... last node
int LL_AddNode(LL *list, void * add); // Adds node AFTER current one
int LL_InsertNode(LL *list, void * add);// Adds node BEFORE current one
// Removes a node from the link; returns the data from the node
void * LL_DeleteNode(LL *list);
// Removes a specific node...
void * LL_Remove(LL *list, void * data);
// Stack operations
int LL_Push(LL *list, void *add); // Add node to end of list
void * LL_Pop(LL *list); // Remove node from end of list
void * LL_Top(LL *list); // Peek at end node
void * LL_Shift(LL *list); // Remove node from start of list
void * LL_Look(LL *list); // Peek at first node
int LL_Unshift(LL *list, void *add); // Add node to beginning of list
int LL_Roll(LL *list); // Make first node last
int LL_UnRoll(LL *list);// Roll the other way...
// Queue operations...
//int LL_Enqueue(LL *list, void *add);
//void * LL_Dequeue(LL *list);
//////////////////////////////////////////////////////////////////////
// Queue operations...
#define LL_Enqueue(list,add) LL_Push(list,add)
#define LL_Dequeue(list) LL_Shift(list)
int LL_PriorityEnqueue(LL *list, void *add, int compare(void *, void *));
int LL_SwapNodes(LL_node *one, LL_node *two); // Switch two nodes positions...
int LL_nSwapNodes(int one, int two); // Switch two nodes positions...
int LL_Length(LL *list); // Returns # of nodes in entire list
// Searching...
void * LL_Find(LL *list, int compare(void *, void *), void *value);
// Sorts the list...
int LL_Sort(LL *list, int compare(void *, void *));
// Debugging...
void LL_dprint(LL *list);
#endif
+41
View File
@@ -0,0 +1,41 @@
########################################################################
# You shouldn't need to touch anything below here.
########################################################################
include ../Makefile.config
TARGET = libLCDstuff.a
OBJ = LL.o sockets.o str.o
#OBJ = LL.o config.o sockets.o
#TODO: config and sockets stuff...
###################################################################
# Compilation...
#
all: $(TARGET)
$(TARGET): $(OBJ) Makefile
ar rcs $(TARGET) $(OBJ)
#$(TARGET): $(OBJ) Makefile
# $(GCC) -s $(MISC) -o $(TARGET) $(OBJ) $(LIB)
%.o: %.c %.h Makefile
$(GCC) -c $(MISC) $<
##################################################################
# Installation
#
install: $(TARGET)
@echo No shared stuff will be installed...
##################################################################
# Other stuff...
#
clean:
rm -f $(OBJ) $(TARGET) *~ core
edit:
emacs . &
+158
View File
@@ -0,0 +1,158 @@
#include "config.h"
typedef struct command
{
char *text;
struct command *child;
int (*func)(char *line);
};
command main_list[] = {
"Key", NULL, Key_func,
"Driver", Driver_commands,NULL,
NULL, NULL, NULL,
};
command Driver_commands[] = {
"MtxOrb", NULL, MtxOrb_drv_init,
"curses", NULL, curses_drv_init,
"hd44780", NULL, hd44780_drv_init,
// "X11", NULL, X11_drv_init,
// "debug", NULL, debug_drv_init,
"text", NULL, text_drv_init,
};
// Interpret a line...
int parse_line(char *line);
// Interpret the rest of the line...
int parse_rest(char *line, command *commands);
////////// Helper functions for line parsing /////////////////
// Pops off the first word of the string.
char *shift(char *string);
////////////// Config Functions /////////////////////////////////
int Key_func(char *line)
{
// uh, interpret the command...
return 0;
}
int parse_line(char *line, command *commands)
{
int i, j;
int newtoken, inquote;
char *str;
// char *tok;
int argc;
char *argv[256];
char delimiters[] = " \0";
char leftquote[] = "\0\"'`([{\0";
char rightquote[] = "\0\"'`)]}\0";
char errmsg[256];
int invalid=0;
int err=0;
// And parse all its messages...
//debug("parse: Getting messages...\n");
str = strdup(line);
debug("parse: ...%s\n", str);
// Now, split up the string...
//len = strlen(str);
argc=0;
newtoken=1;
inquote=0;
for(i=0; str[i]; i++)
{
if(inquote) // Scan for the end of the quote
{
if(str[i] == rightquote[inquote])
{ // Found the end of the quote
inquote=0;
str[i] = 0;
newtoken=1;
}
}
else // Normal operation; split at delimiters
{
for(j=1; leftquote[j]; j++)
{
// Found the beginning of a new quote...
if(str[i] == leftquote[j])
{
inquote = j;
str[i] = 0;
continue;
}
}
for(j=0; delimiters[j]; j++)
{
// Break into a new string...
if(str[i] == delimiters[j])
{
str[i] = 0;
newtoken = 1;
continue;
}
}
}
if(newtoken && str[i])
{
newtoken=0;
argv[argc] = str + i;
argc++;
}
else
{
}
}
if(inquote)
{
sprintf(errmsg, "huh? Unterminated string: missing %c\n",
rightquote[inquote]);
sock_send_string(c->sock, errmsg);
continue;
}
/*
for(tok = strtok(str, delimiters);
tok;
tok=strtok(NULL, delimiters))
{
argv[argc] = tok;
argc++;
}
*/
argv[argc] = NULL;
if(argc < 1) continue;
// Now find and call the appropriate function...
// debug("parse: Finding function...\n");
invalid = 1;
for(i=0; commands[i].keyword; i++)
{
// debug("(checking %s)\n", commands[i].keyword);
if(0 == strcmp(argv[0], commands[i].keyword))
{
// debug("(FOUND %s)\n", commands[i].keyword);
invalid = commands[i].function(c, argc, argv);
// debug("parse: Returned %i...\n", err);
}
}
if(invalid)
{
// FIXME: Check for buffer overflows here...
err = 1;
//sprintf(errmsg, "huh? Invalid command \"%s\"\n", argv[0]);
//sock_send_string(c->sock, errmsg);
}
free(str); // Don't want to forget this... :)
return err;
}
+12
View File
@@ -0,0 +1,12 @@
#ifndef CONFIG_H
#define CONFIG_H
// Read entire config file
int config_load_file(char *file);
// Save new options
int config_save_file(char *file);
#endif
+14
View File
@@ -0,0 +1,14 @@
#ifndef DEBUG_H
#define DEBUG_H
#ifdef DEBUG
#define debug printf
#else
#define debug /* printf */
#endif
#endif
+183
View File
@@ -0,0 +1,183 @@
#include <unistd.h>
#include <stddef.h>
#include <stdio.h>
#include <errno.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <sys/time.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <netdb.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <fcntl.h>
#include "debug.h"
#include "sockets.h"
/**************************************************
LCDproc client sockets code...
Feel free to use this in your own clients... :)
**************************************************/
// Length of longest transmission allowed at once...
#define MAXMSG 8192
typedef struct sockaddr_in sockaddr_in;
static int sock_init_sockaddr (sockaddr_in *name,
const char *hostname,
unsigned short int port)
{
struct hostent *hostinfo;
name->sin_family = AF_INET;
name->sin_port = htons (port);
hostinfo = gethostbyname (hostname);
if (hostinfo == NULL)
{
fprintf (stderr,"sock_init_sockaddr: Unknown host %s.\n", hostname);
return -1;
}
name->sin_addr = *(struct in_addr *) hostinfo->h_addr;
return 0;
}
// Client functions...
int sock_connect(char *host, unsigned short int port)
{
struct sockaddr_in servername;
int sock;
int err=0;
debug("sock_connect: Creating socket\n");
sock = socket(PF_INET, SOCK_STREAM, 0);
if(sock < 0)
{
perror("sock_connect: Error creating socket");
return sock;
}
debug("sock_connect: Created socket (%i)\n", sock);
sock_init_sockaddr(&servername, host, port);
err = connect (sock,
(struct sockaddr *) &servername,
sizeof (servername));
if(err<0)
{
perror("sock_connect: connect failed");
shutdown(sock, 2);
return 0; // Normal exit if server doesn't exist...
}
fcntl(sock, F_SETFL, O_NONBLOCK);
return sock;
}
int sock_close(int fd)
{
int err;
err=shutdown(fd, 2);
return err;
}
// Send/receive lines of text
int sock_send_string(int fd, char *string)
{
int err;
if(!string) return -1;
err = write (fd, string, strlen(string) + 1);
if (err < 0)
{
perror ("sock_send_string: socket write error");
printf("Message was: %s\n", string);
//shutdown(fd, 2);
return err;
}
//printf("sock_send_string: %i bytes\n", err);
return err;
}
// Recv gives only one line per call...
int sock_recv_string(int fd, char *dest, size_t maxlen)
{
char * err;
int i;
// TODO: Get this function to work right somehow...
return -1;
if(!dest) return -1;
if(maxlen <= 0) return 0;
// Read in characters until the end of the line...
for(i=0;
i<maxlen && (read(fd, dest+i, 1) > 0);
i++)
if(dest[i] == 0 || dest[i] == '\n') break;
if (err == NULL)
{
perror("sock_recv_string: socket read error");
//shutdown(fd, 2);
return -1;
}
printf("sock_recv_string: Got message \"%s\"\n", dest);
return strlen(dest);
}
// Send/receive raw data
int sock_send(int fd, void *src, size_t size)
{
int err;
if(!src) return -1;
err = write (fd, src, size);
if (err < 0)
{
perror("sock_send: socket write error");
//shutdown(fd, 2);
return err;
}
return err;
}
int sock_recv(int fd, void *dest, size_t maxlen)
{
int err;
if(!dest) return -1;
if(maxlen <= 0) return 0;
err = read (fd, dest, maxlen);
if (err < 0)
{
//fprintf (stderr,"sock_recv: socket read error\n");
//shutdown(fd, 2);
return err;
}
//debug("sock_recv: Got message \"%s\"\n", (char *)dest);
return err;
}
+87
View File
@@ -0,0 +1,87 @@
#ifndef SOCKETS_H
#define SOCKETS_H
#include <stdlib.h>
#ifndef LCDPORT
#define LCDPORT 13666
#endif
/*
Socket functions available to server and clients...
(ignore the rest of the comments... I was babbling out random ideas)
This should have stuff to read/write sockets, open/close them, etc...
*/
// Client functions...
int sock_connect(char *host, unsigned short int port);
int sock_close(int fd);
// Send/receive lines of text
int sock_send_string(int fd, char *string);
// Recv gives only one line per call...
int sock_recv_string(int fd, char *dest, size_t maxlen);
// Send/receive raw data
int sock_send(int fd, void *src, size_t size);
int sock_recv(int fd, void *dest, size_t maxlen);
// Er, ignore the rest of this file. I'll clean it up sometime...
/*****************************************************************
LCDproc command line interface?: (while running)
-command
Tells LCDproc to interpret stdin as raw commands to send through
the socket. Input must be formatted as above, in socket interface.
-function f
Runs LCDproc external function f, where f is one of the predefined
functions which can be assigned to keypad keys. (like NEXTMODE, etc)
-key x
Simulates keypad press of key 'x', where 'x' is (A-Z).
-print [time]
Prints stdin on LCD one line at a time, with no line-wrapping (raw),
with [time] frames between updates (lines).
-wrap [time]
Prints stdin as with "-print", but with line wrapping when possible.
-contrast xxx
Sets contrast to xxx (decimal)
-backlight [on/off]
Turns backlight [on/off/auto], or toggles it.
If [off], stays off.
If [on], stays on.
If [auto], LCDproc controls backlight based on load, etc...
-exit
-quit
Duh... :)
******************************************************************/
/*****************************************************************
LCDproc stuff supported in config file (loose approximation):
Grammar is tcl-style. I.e., "command arg1 arg2 ...".
Spaces are used as argument separators, *until* it thinks it has the final
argument. So, "function thing shell myprogram arg1 arg2 arg3" would be
split into "function", "thing", "shell", and "myprogram arg1 arg2 arg3".
User-definable functions (use built-in's to create new ones?):
Function mp3NextSong Shell /usr/local/bin/mp3player -next
Function MySequence Sequence cpu mem xload
Function OtherSequence Sequence time cd xload
Keypad keys can be bound to any _function_:
Key A mp3NextSong
Key B HaltSystem
Key C Menu
Key D Next/+
Key E OtherSequence
******************************************************************/
#endif
+34
View File
@@ -0,0 +1,34 @@
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "debug.h"
#include "str.h"
int get_args(char **argv, char *str, int max_args)
{
char *delimiters = " \n\0";
char *item;
int i=0;
if(!argv) return -1;
if(!str) return 0;
if(max_args < 1) return 0;
//debug("get_args(%i): string=%s\n", max_args, str);
// Parse the command line...
for(item = strtok(str, delimiters); item; item=strtok(NULL, delimiters))
{
//debug("get_args: item=%s\n", item);
if(i < max_args)
{
argv[i] = item;
i++;
}
else return i;
}
return i;
}
+6
View File
@@ -0,0 +1,6 @@
#ifndef STR_H
#define STR_H
int get_args(char **argv, char *str, int max_args);
#endif