aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAris Adamantiadis <aris@0xbadc0de.be>2009-06-18 23:01:05 +0200
committerAris Adamantiadis <aris@0xbadc0de.be>2009-06-18 23:01:05 +0200
commit3af55a4f49f32ba73af86c6c47f0ed05044eec13 (patch)
treef2daa2a17772ed9c3e18c8cb6c423087f5ae9e93
parentcf482ae3bfb8492d996cfc9e036f5086ff69eed4 (diff)
downloadlibssh-3af55a4f49f32ba73af86c6c47f0ed05044eec13.tar.gz
libssh-3af55a4f49f32ba73af86c6c47f0ed05044eec13.tar.xz
libssh-3af55a4f49f32ba73af86c6c47f0ed05044eec13.zip
Created general singlelinked list implementation
-rw-r--r--include/libssh/priv.h35
-rw-r--r--libssh/misc.c80
2 files changed, 115 insertions, 0 deletions
diff --git a/include/libssh/priv.h b/include/libssh/priv.h
index f344cedd..d0d0ea2d 100644
--- a/include/libssh/priv.h
+++ b/include/libssh/priv.h
@@ -705,6 +705,41 @@ int ssh_file_readaccess_ok(const char *file);
u64 ntohll(u64);
#define htonll(x) ntohll(x)
+/* list processing */
+
+struct ssh_list {
+ struct ssh_iterator *root;
+ struct ssh_iterator *end;
+};
+
+struct ssh_iterator {
+ struct ssh_iterator *next;
+ const void *data;
+};
+
+struct ssh_list *ssh_list_new(void);
+void ssh_list_free(struct ssh_list *list);
+struct ssh_iterator *ssh_list_get_iterator(const struct ssh_list *list);
+void ssh_list_add(struct ssh_list *list, const void *data);
+void ssh_list_remove(struct ssh_list *list, struct ssh_iterator *iterator);
+
+/** @brief fetch the head element of a list and remove it from list
+ * @param list the ssh_list to use
+ * @return the first element of the list
+ */
+const void *_ssh_list_get_head(struct ssh_list *list);
+
+#define ssh_iterator_value(type, iterator)\
+ ((type)((iterator)->data))
+/** @brief fetch the head element of a list and remove it from list
+ * @param type type of the element to return
+ * @param list the ssh_list to use
+ * @return the first element of the list
+ */
+#define ssh_list_get_head(type, ssh_list)\
+ ((type)_ssh_list_head(ssh_list))
+
+
/* channels1.c */
int channel_open_session1(CHANNEL *channel);
int channel_request_pty_size1(CHANNEL *channel, const char *terminal,
diff --git a/libssh/misc.c b/libssh/misc.c
index bd926298..8aa533e8 100644
--- a/libssh/misc.c
+++ b/libssh/misc.c
@@ -149,5 +149,85 @@ const char *ssh_version(int req_version) {
return NULL;
}
+struct ssh_list *ssh_list_new(){
+ struct ssh_list *ret=malloc(sizeof(struct ssh_list));
+ if(!ret)
+ return ret;
+ ret->root=ret->end=NULL;
+ return ret;
+}
+
+void ssh_list_free(struct ssh_list *list){
+ struct ssh_iterator *ptr,*next;
+ ptr=list->root;
+ while(ptr){
+ next=ptr->next;
+ SAFE_FREE(ptr);
+ ptr=next;
+ }
+ SAFE_FREE(list);
+}
+
+struct ssh_iterator *ssh_list_get_iterator(const struct ssh_list *list){
+ return list->root;
+}
+
+static struct ssh_iterator *ssh_iterator_new(const void *data){
+ struct ssh_iterator *iterator=malloc(sizeof(struct ssh_iterator));
+ iterator->next=NULL;
+ iterator->data=data;
+ return iterator;
+}
+
+void ssh_list_add(struct ssh_list *list,const void *data){
+ struct ssh_iterator *iterator=ssh_iterator_new(data);
+ if(!list->end){
+ /* list is empty */
+ list->root=list->end=iterator;
+ } else {
+ /* put it on end of list */
+ list->end->next=iterator;
+ list->end=iterator;
+ }
+}
+
+void ssh_list_remove(struct ssh_list *list, struct ssh_iterator *iterator){
+ struct ssh_iterator *ptr,*prev;
+ prev=NULL;
+ ptr=list->root;
+ while(ptr && ptr != iterator){
+ prev=ptr;
+ ptr=ptr->next;
+ }
+ if(!ptr){
+ /* we did not find the element */
+ return;
+ }
+ /* unlink it */
+ if(prev)
+ prev->next=ptr->next;
+ /* if iterator was the head */
+ if(list->root == iterator)
+ list->root=iterator->next;
+ /* if iterator was the tail */
+ if(list->end == iterator)
+ list->end = prev;
+ SAFE_FREE(iterator);
+}
+
+const void *_ssh_list_get_head(struct ssh_list *list){
+ struct ssh_iterator *iterator=list->root;
+ const void *data;
+ if(!list->root)
+ return NULL;
+ data=iterator->data;
+ list->root=iterator->next;
+ if(list->end==iterator)
+ list->end=NULL;
+ SAFE_FREE(iterator);
+ return data;
+}
+
+
/** @} */
/* vim: set ts=2 sw=2 et cindent: */