--- /dev/null
+#ifndef __GETPATH_H
+#define __GETPATH_H
+
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* getpath th -- get the path of the file name specified by the first parameter
+ * of the function and store the path in its second parmater.
+ * the function returns the length of the path of the file.
+ *
+ * param file_name The file name to get the path
+ * param path The address of the path of the file
+ *
+ * return If successful, the function returns the len of the path.
+ * Otherwise the function returns -1 and sets errno to indicate
+ * the error.
+ *
+ * errors
+ *
+ * [ENOENT] the file name specified as parameter does not exist.
+ *
+ * [ENOMEM] because this function use calloc, errno can be set with
+ * this error code.
+ *
+ */
+int
+getpath(const char* file_name, char** path);
+
+/* translatepath -- path translation
+ *
+ * param totranslate The path to translate.
+ * param transled The address of the translated path.
+ *
+ * return If successful the function returns the len of the translated path.
+ * 0therwise the function returns -1 and sets the global variable errno
+ * to indicate the error.
+ *
+ * errors [ENOTDIR] the path to translate is not a directory.
+
+ * [ENOMEM] because this function use calloc, errno can be set with
+ * this error code.
+ */
+int
+translatepath(const char* totranslate, char** translated);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif /* !__GETPATH_H */
--- /dev/null
+#ifndef __list_H
+#define __list_H
+
+#include <allocator.h>
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef __FN_FINALIZE_T_DEFINED
+typedef int (*fn_finalize_t)(void**);
+#define __FN_FINALIZE_T_DEFINED
+#endif
+
+#ifndef SEEK_SET
+#define SEEK_SET 0
+#endif
+
+#ifndef SEEK_CUR
+#define SEEK_CUR 1
+#endif
+
+#ifndef SEEK_END
+#define SEEK_END 2
+#endif
+
+#ifndef __LINK_T_DEFINED
+typedef struct s_link_t
+{
+ void* item; /* the item associated with the link */
+ struct s_link_t* next; /* address to the next link */
+ struct s_link_t* prev; /* address to the prev link */
+}s_link_t,* link_t;
+#define __LINK_T_DEFINED
+#endif
+
+typedef struct s_list
+{
+ void* item; /* not used */
+ link_t next; /* point to the last node of the list */
+ link_t prev; /* point to the first node of the list */
+ fn_finalize_t fn_finalize; /* not used */
+ int size; /* the number of node contained by the list */
+ link_t cur;
+ int pos;
+}s_list_t,* list_t;
+
+list_t
+list_new(fn_finalize_t fn_finalize);
+
+int
+list_rewind(list_t list);
+
+int
+list_unwind(list_t list);
+
+int
+list_clear(list_t list);
+
+int
+list_free(list_t* list_ptr);
+
+int
+list_push_front(list_t list, void* item);
+
+int
+list_push_back(list_t list, void* item);
+
+void*
+list_pop_back(list_t list);
+
+void*
+list_pop_front(list_t list);
+
+int
+list_remove(list_t list, void* item);
+
+int
+list_get_size(list_t list);
+int
+list_contains(list_t list, void* item);
+
+int
+list_is_empty(list_t list);
+
+int
+list_is_autodelete(list_t list);
+
+int
+list_move_next(list_t list);
+
+void*
+list_get(list_t list);
+
+void*
+list_set(list_t list, void* item);
+
+void*
+list_get_at(list_t list, int pos);
+
+void*
+list_set_at(list_t list, int pos, void* item);
+
+int
+list_move_prev(list_t list);
+
+int
+list_seek(list_t list, int offset, int whence);
+
+int
+list_tell(list_t list);
+
+int
+list_getpos(list_t list, int* pos);
+
+int
+list_setpos(list_t list, int pos);
+
+
+void*
+list_get_front(list_t list);
+
+void*
+list_get_back(list_t list);
+
+int
+list_insert_after(list_t list, void* what, void* where);
+
+int
+list_insert_before(list_t list, void* what, void* where);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif /* !__list_H */
--- /dev/null
+#ifndef __STR_REPLACE_H
+#define __STR_REPLACE_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+int
+str_replace(char** str, const char *what, const char *with);
+
+int
+str_replace_all(char** str, const char* what, const char* with);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* !__STR_REPLACE_H */
--- /dev/null
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <pwd.h>
+#include <errno.h>
+#include <getpath.h>
+
+#ifndef MAX_PATH
+#define MAX_PATH 255
+#endif
+
+int
+getpath(const char* file, char** path)
+{
+ char buffer1[MAX_PATH + 1] = {0};
+ char buffer2[MAX_PATH + 1] = {0};
+ char buffer3[MAX_PATH + 1] = {0};
+ char *p1,*p2;
+ size_t len = strlen(file);
+ char* last_delimiter = NULL;
+ struct stat buffer = {0};
+
+ strncpy(buffer1, file, len);
+
+ /* remove the /////// */
+ while((p1 = strstr(buffer1, "//")))
+ {
+ if(p1[2])
+ strcpy(p1, p1 + 1);
+ else
+ p1[1] = '\0';
+ }
+
+ if(*buffer1 == '~')
+ {
+ for(p2 = buffer2, p1 = buffer1 + 1; *p1 && (*p1 != '/'); *p2++ = *p1++);
+ *p2 = '\0';
+
+ if(buffer2[0] == '\0')
+ {
+ char* home = getenv("HOME");
+
+ if(home)
+ {
+ strcpy(buffer2, home);
+ }
+ else
+ {
+ struct passwd* pw = getpwuid(getuid());
+
+ if(!pw)
+ {
+ *path = NULL;
+ return -1;
+ }
+
+ strcpy(buffer2,pw->pw_dir);
+ }
+
+ strcat(buffer2, p1);
+ }
+
+ }
+ else if (buffer1[0] != '/')
+ {
+
+ getcwd(buffer2, MAX_PATH + 1);
+
+ if(buffer1[0] == '.' && buffer1[1] == '/')
+ { /* replace */
+ strcat(buffer2, &buffer1[1]);
+ }
+ else
+ {
+ strcat(buffer2, "/");
+ strcat(buffer2, buffer1);
+ }
+ }
+ else
+ {
+ strcpy(buffer2, buffer1); /* copy */
+ }
+
+ /*
+ * check for /..
+ */
+ while((p1 = strstr( buffer2, "/.." )))
+ {
+ for( p2 = p1; --p2 > buffer2 && *p2 != '/'; );
+
+ if (*(p1 + 3))
+ strcpy(p2, p1 + 3);
+ else
+ *p2 = '\0';
+ }
+
+ /*
+ * try to find links, and resolve them.
+ */
+ p1 = strtok( buffer2, "/" );
+
+ *buffer3 = '\0';
+
+ while(p1)
+ {
+ strcat( buffer3, "/" );
+ strcat( buffer3, p1 );
+
+ len = readlink(buffer3, buffer1, MAX_PATH);
+
+ if (len != -1)
+ {
+ *(buffer1 + len) = '\0';
+ strcpy(buffer3, buffer1 );
+ }
+
+ p1 = strtok( NULL, "/" );
+ }
+
+ if(stat(buffer3, &buffer) || !S_ISREG(buffer.st_mode))
+ {
+ *path = NULL;
+ errno = ENOENT;
+ return -1;
+ }
+
+ last_delimiter = strrchr(buffer3, '/');
+
+ len = strlen(buffer3);
+
+ if(last_delimiter)
+ len -=strlen(last_delimiter);
+
+ *path = (char*) calloc(len + 1, sizeof(char));
+
+ if(!(*path))
+ {
+ *path = NULL;
+ return -1;
+ }
+
+ strncpy(*path, buffer3, len);
+
+ return len;
+}
+
+#include <stdio.h>
+
+int
+translatepath(const char* totranslate, char** translated)
+{
+ char buffer1[MAX_PATH + 1] = {0};
+ char buffer2[MAX_PATH + 1] = {0};
+ char buffer3[MAX_PATH + 1] = {0};
+ char *p1,*p2;
+ size_t len;
+ struct stat buffer = {0};
+
+ len = strlen(totranslate);
+
+ strncpy(buffer1, totranslate, len);
+
+ if(!strcmp(buffer1,"."))
+ {
+ *translated = getcwd(NULL,0);
+ return strlen(*translated);
+ }
+ else if(!strcmp(buffer1, "/.."))
+ {
+ *translated = strdup("/");
+ return strlen(*translated);
+ }
+
+ while((p1 = strstr(buffer1, "//")))
+ if(p1[2])
+ strcpy(p1, p1 + 1);
+ else
+ p1[1] = '\0';
+
+
+
+ if (buffer1[0] == '~')
+ {
+ for (p2 = buffer2, p1 = buffer1 + 1; *p1 && (*p1 != '/'); *(p2++) = *(p1++));
+
+ *p2 = '\0';
+
+ if(buffer2[0] == '\0')
+ {
+ char* home = getenv("HOME");
+
+ if(home)
+ {
+ strcpy(buffer2, home);
+ }
+ else
+ {
+ struct passwd* pw = getpwuid(getuid()); /* get entry */
+
+ if(!pw)
+ {
+ *translated = NULL;
+ return -1;
+ }
+
+ strcpy(buffer2,pw->pw_dir);
+ }
+
+ strcat(buffer2, p1);
+ }
+ }
+ else if (*buffer1 != '/')
+ {
+
+ getcwd(buffer2, MAX_PATH + 1);
+
+ if (*buffer1 == '.' && *(buffer1 + 1) == '/')
+ {
+ strcat(buffer2, buffer1+1);
+ }
+ else
+ {
+ strcat(buffer2, "/");
+ strcat(buffer2, buffer1);
+ }
+ }
+ else
+ {
+ strcpy(buffer2, buffer1);
+ }
+
+ /*
+ * check for /..
+ */
+ while((p1 = strstr( buffer2, "/.." )))
+ {
+ for( p2 = p1; --p2 > buffer2 && *p2 != '/'; );
+
+ if (*(p1 + 3))
+ strcpy(p2, p1 + 3);
+ else
+ *p2 = '\0';
+ }
+
+ /*
+ * try to find links.
+ */
+ p1 = strtok( buffer2, "/" );
+
+
+ *buffer3 = '\0';
+
+ while(p1)
+ {
+ strcat( buffer3, "/" );
+ strcat( buffer3, p1 );
+
+ len = readlink(buffer3, buffer1, MAX_PATH);
+
+ if (len != -1)
+ {
+ *(buffer1 + len) = '\0';
+ strcpy(buffer3, buffer1 );
+ }
+
+ p1 = strtok( NULL, "/" );
+ }
+
+ if (!(*buffer3))
+ strcpy(buffer3, "/" );
+
+ len = strlen(buffer3);
+
+ if(stat(buffer3, &buffer) || !S_ISDIR(buffer.st_mode))
+ {
+ *translated = NULL;
+ errno = ENOTDIR;
+ return -1;
+ }
+
+
+ *translated = (char*) calloc(len + 1, sizeof(char));
+
+ if(!(*translated))
+ {
+ *translated = NULL;
+ return -1;
+ }
+
+ strncpy(*translated, buffer3, len);
+
+ return len;
+}
+
+
--- /dev/null
+
+#include <list.h>
+#include <errno.h>
+#include <stdlib.h>
+
+#define __DEFAULT_BLOCK_CAPACITY 128
+
+static allocator_t
+allocator = NULL;
+
+static int
+ref = 0;
+
+static link_t
+link_new(void* item)
+{
+ link_t link;
+
+ if(!item)
+ {
+ errno = EINVAL;
+ return NULL;
+ }
+
+ if(!(link = (link_t)allocator_alloc(allocator)))
+ return NULL;
+
+ link->next = link->prev = NULL;
+ link->item = item;
+
+ return link;
+}
+
+static int
+link_free(link_t* ref)
+{
+ if(!(*ref))
+ return EINVAL;
+
+ allocator_dealloc(allocator, *ref);
+ *ref = NULL;
+
+ return 0;
+}
+
+static link_t
+search(list_t list, void* item)
+{
+ register link_t cur = list->next;
+
+ while(cur != ((link_t)&(list->item)))
+ {
+ if(cur->item == item)
+ return cur;
+
+ cur = cur->next;
+ }
+
+ errno = ESRCH;
+ return NULL;
+}
+
+
+
+list_t
+list_new(fn_finalize_t fn_finalize)
+{
+ list_t list = (list_t)calloc(1,sizeof(s_list_t));
+
+ if(!list)
+ return NULL;
+
+ if(!allocator)
+ {
+ if(!(allocator = allocator_new(__DEFAULT_BLOCK_CAPACITY, sizeof(s_link_t), NULL)))
+ {
+ free(list);
+ return NULL;
+ }
+ }
+
+ list->next = list->prev = list->cur = (link_t)(&(list->item));
+ list->fn_finalize = fn_finalize;
+ list->pos = -1;
+ list->size = 0;
+
+ ref++;
+
+ return list;
+}
+
+int
+list_rewind(list_t list)
+{
+ if(!list)
+ {
+ errno = EINVAL;
+ return 0;
+ }
+
+ if(!list->size)
+ {
+ errno = EAGAIN;
+ return 0;
+ }
+
+ list->cur = list->next;
+ list->pos = 0;
+
+ return 1;
+}
+
+int
+list_unwind(list_t list)
+{
+ if(!list)
+ {
+ errno = EINVAL;
+ return 0;
+ }
+
+ if(!list->size)
+ {
+ errno = EAGAIN;
+ return 0;
+ }
+
+ list->cur = list->prev;
+ list->pos = list->size - 1;
+
+ return 1;
+}
+
+int
+list_clear(list_t list)
+{
+ int rv;
+
+ if(!list)
+ return EINVAL;
+
+ if(!list->size)
+ return EAGAIN;
+
+ if(list->fn_finalize)
+ {
+ void* item;
+
+ while((item = list_pop_back(list)))
+ if(0 != (rv = (*(list->fn_finalize))(&item)))
+ return rv;
+ }
+ else
+ while(list_pop_back(list));
+
+ return 0;
+}
+
+int
+list_free(list_t* list_ptr)
+{
+ if(!(*list_ptr))
+ return EINVAL;
+
+ if((*list_ptr)->size)
+ list_clear(*list_ptr);
+
+ if(--ref)
+ allocator_free(&allocator);
+
+ free(*list_ptr);
+ *list_ptr = NULL;
+
+ return 0;
+}
+
+int
+list_push_front(list_t list, void* item)
+{
+ link_t what, where, next;
+
+ if(!list || !item)
+ return EINVAL;
+
+ if(!(what = (link_t)link_new(item)))
+ return errno;
+
+ where = (link_t)(&(list->item));
+ next = where->next;
+
+ what->prev = where;
+ what->next = next;
+ next->prev = what;
+ where->next = what;
+
+ list->size++;
+
+ /* the iteration functions are now not permited */
+ list->pos = -1;
+ list->cur = (link_t)(&(list->item));
+
+ return 0;
+}
+
+int
+list_push_back(list_t list, void* item)
+{
+ link_t what, where, prev;
+
+ if(!list || !item)
+ return EINVAL;
+
+ if(!(what = (link_t)link_new(item)))
+ return errno;
+
+ where = (link_t)(&(list->item));
+ prev = where->prev;
+ what->next = where;
+ what->prev = prev;
+ prev->next = what;
+ where->prev = what;
+
+ list->size++;
+
+ /* the iteration functions are now not permited */
+ list->pos = -1;
+ list->cur = (link_t)(&(list->item));
+
+ return 0;
+}
+
+int
+list_insert_after(list_t list, void* what, void* where)
+{
+ link_t __what, __where, __next;
+
+ if(!list || !what || !where)
+ return EINVAL;
+
+ if(!(__what = link_new(what)))
+ return errno;
+
+ if((__where = search(list, where)))
+ return errno;
+
+ __next = __where->next;
+
+ __what->prev = __where;
+ __what->next = __next;
+ __next->prev = __what;
+ __where->next = __what;
+
+ list->size++;
+
+ return 0;
+}
+
+int
+list_insert_before(list_t list, void* what, void* where)
+{
+ link_t __what, __where, __prev;
+
+ if(!list || !what || !where)
+ return EINVAL;
+
+ if(!(__what = link_new(what)))
+ return errno;
+
+ if((__where = search(list, where)))
+ return errno;
+
+ __prev = __where->prev;
+
+ __what->next = __where;
+ __what->prev = __prev;
+ __prev->next = __what;
+ __where->prev = __what;
+
+ list->size++;
+
+ return 0;
+}
+
+
+void*
+list_pop_back(list_t list)
+{
+ link_t link, next, prev;
+ void* item;
+
+ if(!list)
+ {
+ errno = EINVAL;
+ return NULL;
+ }
+
+ if(!list->size)
+ {
+ errno = EAGAIN;
+ return NULL;
+ }
+
+ link = list->prev;
+
+ next = link->next;
+ prev = link->prev;
+ prev->next = next;
+ next->prev = prev;
+
+ list->size--;
+
+ item = link->item;
+
+ link_free((link_t*)&link);
+
+ /* the iteration functions are now not permited */
+ list->pos = -1;
+ list->cur = (link_t)(&(list->item));
+
+ return item;
+}
+
+void*
+list_pop_front(list_t list)
+{
+
+ link_t link, next, prev;
+ void* item;
+
+ if(!list)
+ {
+ errno = EINVAL;
+ return NULL;
+ }
+
+ if(!list->size)
+ {
+ errno = EAGAIN;
+ return NULL;
+ }
+
+ link = list->next;
+
+ next = link->next;
+ prev = link->prev;
+ prev->next = next;
+ next->prev = prev;
+
+ list->size--;
+
+ item = link->item;
+ link_free((link_t*)&link);
+
+ /* the iteration functions are now not permited */
+ list->pos = -1;
+ list->cur = (link_t)(&(list->item));
+
+ return item;
+}
+
+int
+list_remove(list_t list, void* item)
+{
+ link_t link, next, prev;
+
+ if(!list || !item)
+ return EINVAL;
+
+ if(!list->size)
+ return EAGAIN;
+
+ if(!(link = search(list, item)))
+ return errno;
+
+ next = link->next;
+ prev = link->prev;
+ prev->next = next;
+ next->prev = prev;
+
+ list->size--;
+
+ /* the iteration functions are now not permited */
+ list->pos = -1;
+ list->cur = (link_t)(&(list->item));
+
+ return link_free((link_t*)&link);
+}
+
+int
+list_get_size(list_t list)
+{
+ if(!list)
+ {
+ errno = EINVAL;
+ return -1;
+ }
+
+ return list->size;
+}
+
+int
+list_contains(list_t list, void* item)
+{
+ register link_t cur;
+
+ if(!list || !item)
+ {
+ errno = EINVAL;
+ return 0;
+ }
+
+ if(!list->size)
+ {
+ errno = EAGAIN;
+ return 0;
+ }
+
+ cur = list->next;
+
+ while(cur != ((link_t)&(list->item)))
+ {
+ if(cur->item == item)
+ return 1;
+
+ cur = cur->next;
+ }
+
+ return 0;
+}
+
+int
+list_is_empty(list_t list)
+{
+ if(!list)
+ {
+ errno = EINVAL;
+ return 0;
+ }
+
+ return !list->size;
+}
+
+int
+list_is_autodelete(list_t list)
+{
+ if(!list)
+ {
+ errno = EINVAL;
+ return 0;
+ }
+
+ return NULL != list->fn_finalize;
+}
+
+int
+list_move_next(list_t list)
+{
+ if(!list)
+ {
+ errno = EINVAL;
+ return 0;
+ }
+
+ if(!list->size || (-1 == list->pos))
+ {
+ errno = EAGAIN;
+ return 0;
+ }
+
+ if(list->cur != (link_t)(&(list->item)))
+ {
+ list->cur = list->cur->next;
+ list->pos++;
+ return 1;
+ }
+
+ list->pos = -1;
+ errno = ERANGE;
+ return 0;
+}
+
+void*
+list_get(list_t list)
+{
+ if(!list)
+ {
+ errno = EINVAL;
+ return NULL;
+ }
+
+ if(!list->size || (-1 == list->pos))
+ {
+ errno = EAGAIN;
+ return NULL;
+ }
+
+ return list->cur->item;
+}
+
+void*
+list_set(list_t list, void* item)
+{
+ void* prev_item;
+
+ if(!list || !item)
+ {
+ errno = EINVAL;
+ return NULL;
+ }
+
+ if(!list->size || (-1 == list->pos))
+ {
+ errno = EAGAIN;
+ return NULL;
+ }
+
+ prev_item = list->cur->item;
+ list->cur->item = item;
+
+ return prev_item;
+}
+
+void*
+list_get_at(list_t list, int pos)
+{
+ register link_t cur;
+
+ if(!list)
+ {
+ errno = EINVAL;
+ return NULL;
+ }
+
+ if(pos < 0 || pos >= list->size)
+ {
+ errno = ERANGE;
+ return NULL;
+ }
+
+ if(!list->size)
+ {
+ errno = EAGAIN;
+ return NULL;
+ }
+
+ cur = list->next;
+
+ while(pos--)
+ cur = cur->next;
+
+
+ return cur->item;
+}
+
+void*
+list_set_at(list_t list, int pos, void* item)
+{
+ register link_t cur;
+ void* prev_item;
+
+ if(!list || !item)
+ {
+ errno = EINVAL;
+ return NULL;
+ }
+
+ if(pos < 0 || pos >= list->size)
+ {
+ errno = ERANGE;
+ return NULL;
+ }
+
+ if(!list->size)
+ {
+ errno = EAGAIN;
+ return NULL;
+ }
+
+ cur = list->next;
+
+ while(pos--)
+ cur = cur->next;
+
+ prev_item = cur->item;
+ cur->item = item;
+
+ return prev_item;
+
+}
+
+int
+list_move_prev(list_t list)
+{
+ if(!list)
+ {
+ errno = EINVAL;
+ return 0;
+ }
+
+ if(!list->size || (-1 == list->pos))
+ {
+ errno = EAGAIN;
+ return 0;
+ }
+
+ if(list->cur != (link_t)(&(list->item)))
+ {
+ list->cur = list->cur->prev;
+ list->pos--;
+ return 1;
+ }
+
+ list->pos = -1;
+ errno = ERANGE;
+ return 0;
+}
+
+static int
+seek_set(list_t list, int offset)
+{
+ if(offset > list->size)
+ return EINVAL;
+
+ list_rewind(list);
+
+ while(offset--)
+ list_move_next(list);
+
+ return 0;
+}
+
+static int
+seek_end(list_t list, int offset)
+{
+ if(offset > list->size)
+ return EINVAL;
+
+ list_unwind(list);
+
+ while(offset--)
+ list_move_prev(list);
+
+ return 0;
+}
+
+
+static int
+seek_cur(list_t list, int offset)
+{
+ if(list->cur == list->next)
+ {
+ /* we are at the begin of the list */
+ seek_set(list, offset);
+ }
+ else if(list->cur == list->prev)
+ {
+ /* we are at the end of the list */
+ seek_end(list, offset);
+ }
+ else
+ {
+ if(offset > (list->size - list->pos + 1))
+ return EINVAL;
+
+ while(offset--)
+ list_move_next(list);
+
+ }
+
+ return 0;
+}
+
+int
+list_seek(list_t list, int offset, int whence)
+{
+ if(!list)
+ return EINVAL;
+
+ if(!list->size)
+ return EAGAIN;
+
+ switch(whence)
+ {
+ case SEEK_SET :
+ return seek_set(list, offset);
+
+ case SEEK_CUR :
+ return seek_cur(list, offset);
+
+ case SEEK_END :
+ return seek_end(list, offset);
+
+ }
+
+ return EINVAL;
+}
+
+int
+list_tell(list_t list)
+{
+ if(!list)
+ {
+ errno = EINVAL;
+ return -1;
+ }
+
+ if(!list->size || (-1 == list->pos))
+ {
+ errno = EAGAIN;
+ return -1;
+ }
+
+ return list->pos;
+}
+
+int
+list_getpos(list_t list, int* pos)
+{
+
+ if(!list || !pos)
+ {
+ errno = EINVAL;
+ return 0;
+ }
+
+ if(!list->size || (-1 == list->pos))
+ {
+ errno = EAGAIN;
+ return 0;
+ }
+
+ *pos = list->pos;
+ return 1;
+}
+
+int
+list_setpos(list_t list, int pos)
+{
+ if(!list)
+ {
+ errno = EINVAL;
+ return 0;
+ }
+
+ if(pos < 0 || pos >= list->size)
+ {
+ errno = ERANGE;
+ return 0;
+ }
+
+ if(!list->size)
+ {
+ errno = EAGAIN;
+ return 0;
+ }
+
+ list->cur = list->next;
+ list->pos = pos;
+
+ while(pos--)
+ list->cur = list->cur->next;
+
+ return 1;
+}
+
+
+void*
+list_get_front(list_t list)
+{
+ if(!list)
+ {
+ errno = EINVAL;
+ return NULL;
+ }
+
+ if(!list->size)
+ {
+ errno = EAGAIN;
+ return NULL;
+ }
+
+ return list->next->item;
+}
+
+
+void*
+list_get_back(list_t list)
+{
+ if(!list)
+ {
+ errno = EINVAL;
+ return NULL;
+ }
+
+ if(!list->size)
+ {
+ errno = EAGAIN;
+ return NULL;
+ }
+
+ return list->prev->item;
+}
--- /dev/null
+#include <str_replace.h>
+#include <string.h>
+#include <errno.h>
+#include <stdlib.h>
+
+#include <stdio.h>
+
+int
+str_replace(char** str, const char* what, const char* with)
+{
+ int pos, i;
+ char* begin;
+ char* buf;
+
+ if(!(begin = strstr(*str, what)))
+ {
+ errno = ESRCH;
+ return -1;
+ }
+
+ pos = begin - *str;
+
+ i = 0;
+
+ /*while(begin[i] != ' ' && begin[i] != '\n' && begin[i] != '\r' && begin[i] != '\0')
+ i++;
+
+ pos += i;
+ */
+
+ pos += strlen(what);
+
+ if(begin == *str)
+ {
+ if(!(buf = (char*) calloc(strlen(with) + ((pos < strlen(*str)) ? strlen(*str + pos) : 0) + 1, sizeof(char))))
+ return -1;
+
+ strcpy(buf, with);
+
+ if(pos < strlen(*str))
+ strcpy(buf + strlen(with), *str + pos);
+ }
+ else
+ {
+ if(!(buf = (char*) calloc((begin - *str) + strlen(with) + ((pos < strlen(*str)) ? strlen(*str + pos) : 0) + 1, sizeof(char))))
+ return -1;
+
+ strncpy(buf, *str, (begin - *str));
+ strcpy(buf + (begin - *str) , with);
+
+
+ if(pos < strlen(*str))
+ strcpy(buf + (begin - *str) + strlen(with), *str + pos);
+ }
+
+ free(*str);;
+ *str = buf;
+
+ return 0;
+
+}
+
+int
+str_replace_all(char** str, const char* what, const char* with)
+{
+ int rv;
+
+ while(!(rv = str_replace(str, what, with)));
+
+ return (errno == ESRCH) ? 0 : -1;
+}
+
+