summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorpancake <pancake@dazo>2008-03-05 18:38:42 +0100
committerpancake <pancake@dazo>2008-03-05 18:38:42 +0100
commit2ddb2923c68d023f9733fb82bb8d28140ea5b695 (patch)
tree706162ce4107ec1444870ad4945a9e6d5a0cde91
parent32a59f4279e1d72abc2b60f08d6e32e2a0b32478 (diff)
download0xFFFF-2ddb2923c68d023f9733fb82bb8d28140ea5b695.tar.bz2
* Initial import of the GtkAML gui frontend - Mostly implemented in just one night :)
* Import the squeue c and vapi sources * Make 0xFFFF run as squeue daemon with -Q flag * Up to 0.4
-rw-r--r--config.mk2
-rw-r--r--src/Makefile3
-rw-r--r--src/gui/Makefile6
-rw-r--r--src/gui/gui.gtkaml269
-rw-r--r--src/main.c26
-rw-r--r--src/main.h2
-rw-r--r--src/os.h10
-rw-r--r--src/qmode.c83
-rw-r--r--src/squeue/squeue.c250
-rw-r--r--src/squeue/squeue.h27
-rw-r--r--src/squeue/squeue.vapi43
11 files changed, 714 insertions, 7 deletions
diff --git a/config.mk b/config.mk
index a8d435c..71cf2ec 100644
--- a/config.mk
+++ b/config.mk
@@ -1,4 +1,4 @@
-VERSION=0.3.2
+VERSION=0.3.9
PREFIX=/usr
# NetBSD stuff
diff --git a/src/Makefile b/src/Makefile
index de2ba2e..9610497 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -1,6 +1,7 @@
include ../config.mk
-OBJ=main.o fiasco.o hexdump.o dump.o flash.o serial.o
+OBJ=main.o fiasco.o hexdump.o dump.o flash.o serial.o qmode.o
OBJ+=hash.o fpid.o query.o pieces.o utils.o devices.o console.o
+OBJ+=squeue/squeue.o
BIN=0xFFFF
#LIBS=`${HAVE_USB} && echo -- '-lusb'`
LIBS=`if [ "${HAVE_USB}" = 1 ]; then echo '-lusb'; fi`
diff --git a/src/gui/Makefile b/src/gui/Makefile
new file mode 100644
index 0000000..661bf66
--- /dev/null
+++ b/src/gui/Makefile
@@ -0,0 +1,6 @@
+all:
+ gtkamlc --Xcc=-I../squeue ../squeue/squeue.c ../squeue/squeue.vapi gui.gtkaml --pkg gtk+-2.0 -o a.out
+
+test:
+ valac --save-temps --Xcc=-I.. squeue.vapi test.vala ../squeue.c -o v
+ valac --save-temps --Xcc=-I.. squeue.vapi client.vala ../squeue.c -o c
diff --git a/src/gui/gui.gtkaml b/src/gui/gui.gtkaml
new file mode 100644
index 0000000..8094da2
--- /dev/null
+++ b/src/gui/gui.gtkaml
@@ -0,0 +1,269 @@
+<!--
+
+ Frontend for the 0xFFFF flasher in gtkaml
+
+ author: pancake <youterm.com>
+
+-->
+
+<Window xmlns='Gtk' xmlns:SQueues='SQueues' xmlns:GLib='GLib' xmlns:class="http://gtkaml.org/0.2"
+ class:name="MainWindow" title="0xFFFF GUI" delete-event="{OnWindow1DeleteEvent}">
+<VBox>
+ <MenuBar expand="false">
+ <MenuItem label="_File" with-mnemonic="true">
+ <submenu>
+ <Menu>
+ <ImageMenuItem stock-id="gtk-new" activate="{OnFileNewEvent}"/>
+ <ImageMenuItem stock-id="gtk-open" activate="{OnFileOpenEvent}"/>
+ <SeparatorMenuItem />
+ <ImageMenuItem stock-id="gtk-quit" activate="{OnQuitEvent}"/>
+ </Menu>
+ </submenu>
+ </MenuItem>
+
+ <!-- Help menu -->
+ <MenuItem label="_Help" with-mnemonic="true">
+ <submenu>
+ <Menu>
+ <ImageMenuItem stock-id="gtk-about" activate="{OnMenuHelpAboutActivatedEvent}"/>
+ </Menu>
+ </submenu>
+ </MenuItem>
+ </MenuBar>
+
+ <HBox border-width="5">
+ <VBox border-width="3" spacing="3">
+ <ScrolledWindow can-focus="true" hscrollbar-policy="{PolicyType.AUTOMATIC}" vscrollbar-policy="{PolicyType.AUTOMATIC}">
+ <TreeView class:private="tv">
+ </TreeView>
+ </ScrolledWindow>
+
+ <ProgressBar class:private="pb" expand="false" />
+ </VBox>
+ <VBox expand="false" border-width="3" spacing="3">
+ <Button label="gtk-add" use-stock="true" expand="false" clicked="{OnFileOpenEvent}" />
+ <Button label="gtk-remove" use-stock="true" expand="false" clicked="{list_del}"/>
+ <Label label="" />
+ <Button label="gtk-info" use-stock="true" expand="false" clicked="{OnGetInformation}"/>
+ <Button label="Options" use-stock="false" expand="false"/>
+ <Button label="Fiasco!" use-stock="false" expand="false"/>
+ <Button label="Unpack!" use-stock="false" expand="false"/>
+ <Button label="Go flash!" use-stock="false" expand="false"/>
+ </VBox>
+ </HBox>
+
+ <Statusbar expand="false"/>
+</VBox>
+
+ <AboutDialog class:standalone="true" class:private="aboutdialog1" delete-event="{aboutdialog1.hide_on_delete}"
+ border-width="5" title="About 0xFFFF gui" resizable="false" modal="true"
+ window-position="{WindowPosition.CENTER_ON_PARENT}" has-separator="false"
+ program-name="0xFFFF" version="0.4" copyright="Copyright (c) 2008 pancake"
+ comments="The Free Nokia Internet Tablet flasher"
+ website="http://www.nopcode.org/0xFFFF/"
+ authors='{new string[] {"pancake (pancake@youterm.com)", null}}'>
+ </AboutDialog>
+
+<![CDATA[
+private void OnWindow1DeleteEvent ()
+{
+ doCloseApplication ();
+}
+
+private void doCloseApplication ()
+{
+ Gtk.main_quit ();
+}
+
+private void OnFileOpenEvent ()
+{
+ FileChooserDialog fc = new FileChooserDialog("Select file to open",
+ this,
+ FileChooserAction.OPEN,
+ "gtk-cancel",ResponseType.CANCEL,
+ "gtk-open",ResponseType.ACCEPT);
+
+ int resp = fc.run ();
+ fc.hide ();
+ if (resp == ResponseType.ACCEPT)
+ {
+ add_file(fc.get_filename ());
+ }
+ fc.destroy ();
+}
+
+public bool loadFile( string filename )
+{
+ int err = 0;
+ try
+ {
+ string contents; int length;
+ FileUtils.get_contents (filename, out contents, out length);
+ //textview1.buffer.set_text (contents, length);
+ }
+ catch(Error e)
+ {
+ showError ("Unexpected error while loading the file, please contact the author with the following information:\n\n" + e.message);
+ err++;
+ }
+ return err == 0;
+}
+
+public void showMessage(string s, MessageType mt)
+{
+ MessageDialog md = new MessageDialog (this,
+ DialogFlags.DESTROY_WITH_PARENT,
+ mt, ButtonsType.CLOSE, s);
+ md.run ();
+ md.destroy ();
+}
+
+private void OnMenuHelpAboutActivatedEvent ()
+{
+ aboutdialog1.transient_for = this;
+ aboutdialog1.run ();
+}
+
+public void showError (string s)
+{
+ MessageDialog md = new MessageDialog (this,
+ DialogFlags.DESTROY_WITH_PARENT,
+ MessageType.ERROR,
+ ButtonsType.CLOSE,
+ s);
+ md.run ();
+ md.destroy ();
+}
+
+private void OnFileNewEvent ()
+{
+ list_clear();
+ // TODO: clear file list
+}
+
+private void OnQuitEvent ()
+{
+ doCloseApplication();
+}
+
+
+public void list_clear()
+{
+ ((ListStore)tv.model).clear();
+}
+
+public void list_del()
+{
+ TreeIter iter;
+ TreeModel model;
+ string str = "";
+
+ TreeSelection sel = tv.get_selection();
+
+ if (sel.count_selected_rows() == 1) {
+ sel.get_selected(out model, out iter);
+ ((ListStore)tv.model).remove(iter);
+ }
+
+ //return str;
+}
+
+public void add_file(string file)
+{
+ ListStore listmodel = (ListStore)tv.get_model();
+ Gtk.TreeIter iter;
+ listmodel.append (out iter);
+ listmodel.set (iter, 0, "initfs", 1, "3M", 2, file, -1);
+}
+
+public static void setup_treeview (Gtk.TreeView view) {
+
+ /* use liststore to hold accountname, accounttype, balance and color attribute */
+ /* for more info how gtkTreeview works take a look in the GTK API */
+
+ var listmodel = new Gtk.ListStore(4, typeof(string), typeof(string), typeof(string), typeof(string));
+ view.set_model(listmodel);
+
+ view.insert_column_with_attributes (-1, "Type", new Gtk.CellRendererText(), "text", 0, null);
+ view.insert_column_with_attributes (-1, "Size", new Gtk.CellRendererText(), "text", 1, null);
+
+ var cell = new Gtk.CellRendererText ();
+ cell.set ("foreground_set", true, null);
+ view.insert_column_with_attributes (-1, "Name", cell, "text", 2, "foreground", 3, null);
+
+ Gtk.TreeIter iter;
+ listmodel.append (out iter);
+ listmodel.set (iter, 0, "initfs", 1, "3M", 2, "initfs.jffs", -1);
+ //listmodel.set (iter, 0, "initfs", 1, "3M", 2, "initfs.jffs", 3, "green", -1);
+
+ listmodel.append (out iter);
+ listmodel.set (iter, 0, "rootfs", 1, "52M", 2, "rootfs.jffs", -1);
+ }
+
+public static bool readFunc()
+{
+ weak string msg = p->get(0);
+ //string str = "%s".printf(msg);
+ if (msg != null && msg[0]!='\0') {
+ stdout.printf("chk msg found hwhe (%s)\n", msg);
+ viewer.showMessage(msg, MessageType.INFO);
+ p->pop();
+ }
+ return true;
+}
+
+static SQueue *q = null;
+static SQueue *p = null;
+
+private void OnGetInformation()
+{
+stdout.printf("chking\n");
+ msg("foo");
+}
+
+private bool chk_queues()
+{
+ if (p == null)
+ p = SQueue.open("/tmp/0xFFFF.1", SQueueMode.OPEN);
+ if (q == null)
+ q = SQueue.open("/tmp/0xFFFF.2", SQueueMode.OPEN);
+ if (p == null || q == null) {
+ showMessage("Cannot connect to queues", MessageType.ERROR);
+ return false;
+ }
+ return true;
+}
+
+public void msg(string str)
+{
+ if (!chk_queues())
+ return;
+ if (q->push(str, 0)<1) {
+ stderr.printf("Oops on push\n");
+ q->free();
+ q = null;
+ p->free();
+ p = null;
+ }
+}
+
+static MainWindow viewer;
+
+static int main (string[] args)
+{
+ Gtk.init (ref args);
+ viewer = new MainWindow();
+ if (args.length > 1)
+ viewer.loadFile (args[1]);
+ viewer.resize(600,400);
+ viewer.set_position(WindowPosition.CENTER);
+ setup_treeview(viewer.tv);
+ viewer.show_all ();
+ viewer.showMessage("This software is beta and does not guaranties correct functionality", MessageType.WARNING);
+ Timeout.add(600, (SourceFunc)(readFunc));
+ Gtk.main ();
+ return 0;
+}
+
+]]>
+</Window>
diff --git a/src/main.c b/src/main.c
index adec9f8..a4e8cf9 100644
--- a/src/main.c
+++ b/src/main.c
@@ -1,6 +1,6 @@
/*
* 0xFFFF - Open Free Fiasco Firmware Flasher
- * Copyright (C) 2007 pancake <pancake@youterm.com>
+ * Copyright (C) 2007, 2008 pancake <pancake@youterm.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -23,6 +23,10 @@
#include <stdlib.h>
#include <getopt.h>
+#if HAVE_SQUEUE
+#include "squeue/squeue.h"
+#endif
+
/* global pr0n */
#if HAVE_USB
#include <usb.h>
@@ -40,6 +44,7 @@ int verbose = 0;
int identify = 0;
int moboreboot = 0;
int unpack = 0;
+int qmode = 0;
int info = 0;
/* global structs */
@@ -91,6 +96,9 @@ void show_usage()
printf(" -R reboot the omap board\n");
printf(" -U [0|1] disable/enable the usb host mode\n");
#endif
+#if HAVE_SQUEUE
+ printf(" -Q enter shared queues server mode (for gui or remote)\n");
+#endif
printf("Local stuff:\n");
printf(" -s [serial] serial port console (minicom like terminal)\n");
printf(" -h show this help message\n");
@@ -222,7 +230,7 @@ int main(int argc, char **argv)
{
int c;
- while((c = getopt(argc, argv, "C:cp:PvVhRu:ib:U:r:e:ld:I:D:f:F:s:xH:")) != -1) {
+ while((c = getopt(argc, argv, "QC:cp:PvVhRu:ib:U:r:e:ld:I:D:f:F:s:xH:")) != -1) {
switch(c) {
case 'H':
printf("xorpair: %04x\n", do_hash_file(optarg));
@@ -286,6 +294,9 @@ int main(int argc, char **argv)
fiasco_image = optarg;
unpack = 1;
break;
+ case 'Q':
+ qmode = 1;
+ break;
case 'P':
return fiasco_pack(optind, argv);
case 'I':
@@ -306,6 +317,9 @@ int main(int argc, char **argv)
}
}
+ if (qmode)
+ return queue_mode();
+
if (identify)
return 0;
@@ -321,9 +335,11 @@ int main(int argc, char **argv)
&& (usb_mode == -1)
&& (root_device == -1))
{
- printf("0xFFFF [-chilRvVx] [-C mtd-dev] [-d vid:pid] [-D 0|1|2] [-e path] [-f flags]\n");
- printf(" [-F fiasco] [-H hash-file] [-I piece] [-p [piece%%]file]] [-r 0|1]\n");
- printf(" [-s serial-dev] [-u fiasco-image] [-U 0|1] | [-P new-fiasco] [piece1] [2] ..\n");
+
+ printf("# The Free Fiasco Firmware Flasher v"VERSION"\n"
+ "0xFFFF [-chilQRvVx] [-C mtd-dev] [-d vid:pid] [-D 0|1|2] [-e path] [-f flags]\n"
+ " [-F fiasco] [-H hash-file] [-I piece] [-p [piece%%]file]] [-r 0|1]\n"
+ " [-s serial-dev] [-u fiasco-image] [-U 0|1] | [-P new-fiasco] [piece1] [2] ..\n");
return 1;
}
diff --git a/src/main.h b/src/main.h
index 541b4fa..38440b5 100644
--- a/src/main.h
+++ b/src/main.h
@@ -4,6 +4,7 @@
#include "hash.h"
#include "nolo.h"
+#include "os.h"
#define _FILE_OFFSET_BITS 64
#define _GNU_SOURCE
@@ -11,6 +12,7 @@
// Forward declaration for use in function arguments.
struct devices;
+int queue_mode();
int reverse_extract_pieces(char *dir);
void flash_image(char *filename, char *piece, char *version);
int fiasco_read_image(char *file);
diff --git a/src/os.h b/src/os.h
new file mode 100644
index 0000000..03ed2fa
--- /dev/null
+++ b/src/os.h
@@ -0,0 +1,10 @@
+#ifndef _OS_H_
+#define _OS_H_
+
+#if __linux__ || __NetBSD__ || __FreBSD__ || __OpenBSD__ || __Darwin__ || __MacOSX__
+#define HAVE_SQUEUE 1
+#else
+#define HAVE_SQUEUE 0
+#endif
+
+#endif
diff --git a/src/qmode.c b/src/qmode.c
new file mode 100644
index 0000000..7343b2b
--- /dev/null
+++ b/src/qmode.c
@@ -0,0 +1,83 @@
+/*
+ * 0xFFFF - Open Free Fiasco Firmware Flasher
+ * Copyright (C) 2008 pancake <pancake@youterm.com>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "main.h"
+#include "os.h"
+#include <stdio.h>
+#if HAVE_SQUEUE
+#include "squeue/squeue.h"
+
+struct squeue_t *q;
+struct squeue_t *p;
+
+int fork_enabled = 0;
+int dofork()
+{
+ if (fork_enabled)
+ return fork();
+ return 0;
+}
+
+void process_message(char *msg)
+{
+ squeue_push(p, "nice shot!", 0);
+ printf("childa (%s)\n", msg);
+}
+
+int queue_mode()
+{
+ int pid = 0;
+ char *msg;
+
+ pid = dofork();
+ if (pid) {
+ wait(pid);
+ return 0;
+ } else {
+ p = squeue_open("/tmp/0xFFFF.1", Q_CREAT);
+ q = squeue_open("/tmp/0xFFFF.2", Q_CREAT);
+ if (p == NULL || q == NULL) {
+ fprintf(stderr, "Cannot open queue files\n");
+ return 0;
+ }
+ pid = dofork();
+ if (pid) {
+ printf( "Entering into shared queue server mode.\n"
+ "Type $ kill -9 %d # to stop\n"
+ "NOTE: Manually remove the /tmp/.0xFFFF.* files to solve perm problems\n", pid);
+ } else {
+ printf("Waiting for a client in shared queues..\n");
+ setsid();
+ while(1) {
+ msg = squeue_get(q, 1);
+ if (msg) {
+ process_message(msg);
+ squeue_pop(q);
+ }
+ }
+ }
+ }
+ return 0;
+}
+#else
+int queue_mode()
+{
+ /* dummy */
+ fprintf(stderr, "No HAVE_SQUEUE support\n");
+}
+#endif
diff --git a/src/squeue/squeue.c b/src/squeue/squeue.c
new file mode 100644
index 0000000..0386784
--- /dev/null
+++ b/src/squeue/squeue.c
@@ -0,0 +1,250 @@
+#include "squeue.h"
+#include <unistd.h>
+#include <stdlib.h>
+#include <sys/ipc.h>
+#include <signal.h>
+#include <sys/shm.h>
+#include <sys/mman.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <string.h>
+
+#define POOL_SIZE ITEM_MAX*ITEM_SIZE
+#define ITEM_SIZE 80
+#define ITEM_MAX 10
+
+int squeue_release(const char *file)
+{
+ int shmid;
+ key_t k = ftok(file, 0xa3);
+
+ if (k == -1) {
+ perror("ftok");
+ return -1;
+ }
+
+ shmid = shmget(k, POOL_SIZE, 0666);
+ if (shmid == -1)
+ return -1; // not released
+ return shmctl(shmid, IPC_RMID,NULL);
+}
+
+struct squeue_t *squeue_open(const char *file, int mode)
+{
+ struct squeue_t *q;
+ char *pool;
+ int shmid;
+ key_t k = ftok(file, 0xa3);
+_retry:
+ shmid = shmget(k, POOL_SIZE, 0666);
+ if (shmid == -1) {
+ if (mode == Q_WAIT) {
+ usleep(200);
+ goto _retry;
+ }
+ shmid = shmget(k, POOL_SIZE, 0666|IPC_EXCL|((mode==Q_CREAT)?IPC_CREAT:0));
+ if (shmid == -1) {
+ if (mode == Q_WAIT) {
+ usleep(200);
+ goto _retry;
+ }
+ perror("shmget");
+ return NULL;
+ }
+ }
+
+ if (mode == Q_WAIT)
+ mode = Q_OPEN;
+
+ pool = shmat(shmid, NULL, k);
+ if (((int)pool) == -1) {
+ perror("shmat\n");
+ return NULL;
+ }
+
+ if (mode == Q_CREAT)
+ memset(pool, '\0', POOL_SIZE);
+
+ q = (struct squeue_t *)malloc(sizeof(struct squeue_t));
+ memset(q, '\0', sizeof(struct squeue_t));
+ q->shmid = shmid;
+ q->pool = pool;
+ q->mode = mode;
+
+ return q;
+}
+
+void squeue_free(struct squeue_t *q)
+{
+ free(q);
+}
+
+int squeue_close(struct squeue_t *q)
+{
+ char *pool;
+
+ if (q==NULL)
+ return -1;
+
+ pool = q->pool;
+ shmctl(q->shmid, IPC_RMID, NULL);
+ free(q);
+ return shmdt(pool);
+}
+
+int squeue_push(struct squeue_t *q, const char *str, int lock)
+{
+ int i;
+
+ if (q==NULL)
+ return -1;
+// if (q->mode == Q_CREAT) {
+// printf("squeue_push: cannot push from the creator\n");
+// return -1;
+// }
+
+ if (str==NULL||strlen(str)>ITEM_SIZE)
+ return -1;
+ do {
+ if (q->squeue_idx >= ITEM_MAX) {
+ while (q->pool[0]!='\0') {
+ q->squeue_locks++;
+ if (!lock) {
+ printf("buffer is full\n");
+ return -1;
+ }
+ usleep(200);
+ }
+ q->squeue_idx = 0;
+ }
+
+ for(i=q->squeue_idx*ITEM_SIZE;i<POOL_SIZE;i+=ITEM_SIZE) {
+ if (q->pool[i]=='\0') {
+ strcpy(q->pool+i, str);
+ q->squeue_idx++;
+ return 1;
+ }
+ }
+ q->squeue_locks++;
+ } while (lock);
+ q->squeue_lost++;
+
+ return 0;
+}
+
+int squeue_pop(struct squeue_t *q)
+{
+ int i;
+ int two = 1;
+
+ if (q==NULL)
+ return -1;
+// if (q->mode == Q_OPEN) { // cannot pop when not owner of squeue
+// fprintf(stderr, "squeue_pop: cannot pop when you are not owner.\n");
+// return -1;
+// }
+ for(two=1;two--;q->head_idx = 0)
+ for(i=q->head_idx*ITEM_SIZE;i<POOL_SIZE;i+=ITEM_SIZE) {
+ if (q->pool[i]!='\0') {
+ q->pool[i]='\0';
+ q->head_idx++;
+ q->squeue_pops++;
+ return 1;
+ }
+ }
+ q->squeue_oops++;
+ fprintf(stderr, "WARNING: race condition detected in squeue.\n");
+ return 0;
+}
+
+char *squeue_get(struct squeue_t *q, int lock)
+{
+ int i=0;
+ int two = 1;
+
+ if(q==NULL)
+ return NULL;
+// if (q->mode == Q_OPEN) { // cannot pop when not owner of squeue
+// fprintf(stderr, "squeue_get: cannot pop when you are not owner.\n");
+// return NULL;
+// }
+ do {
+ for(two=1;two--;q->head_idx = 0) {
+ for(i=q->head_idx*ITEM_SIZE;i<POOL_SIZE;i+=ITEM_SIZE)
+ if (q->pool[i]!='\0')
+ return q->pool+i;
+ }
+ if (lock)
+ usleep(500);
+ } while (lock);
+ return NULL;
+}
+
+void squeue_stats(struct squeue_t *q)
+{
+ if(q==NULL)
+ return;
+ printf("Queue locks: %d\n", q->squeue_locks);
+ printf("Queue lost: %d\n", q->squeue_lost);
+ printf("Queue oops: %d\n", q->squeue_oops);
+ printf("Queue pops: %d\n", q->squeue_pops);
+}
+
+#if _MAIN_
+struct squeue_t *q;
+
+int sigc()
+{
+ squeue_stats(q);
+ exit(1);
+}
+
+int main()
+{
+ char buf[102];
+ int i;
+ int pid;
+
+ signal(SIGINT, sigc);
+
+ squeue_release("/dev/null");
+
+ pid = fork();
+ if (pid) {
+ q = squeue_open("/dev/null", Q_CREAT);
+ if (q == NULL) {
+ perror("oops");
+ kill(pid, SIGINT);
+ return;
+ }
+ squeue_push(q, "Hello World", 0);
+ squeue_push(q, "jeje msg 2", 0);
+
+ while(1) {
+ char *uh = squeue_get(q,1);
+ if (uh) {
+ printf("get: (%s)\n", uh);
+ squeue_pop(q);
+ }
+ usleep(200);
+ }
+ squeue_close(q);
+ } else {
+ q = squeue_open("/dev/null", Q_WAIT);
+ if (q == NULL) {
+ perror("oops");
+ return;
+ }
+ for(i=0;i<128;i++) {
+ sprintf(buf, "puta%d", i);
+ squeue_push(q, buf, 1);
+ usleep(100);
+ }
+ squeue_stats(q);
+ printf("cya\n");
+ squeue_close(q);
+ }
+
+ return 0;
+}
+#endif
diff --git a/src/squeue/squeue.h b/src/squeue/squeue.h
new file mode 100644
index 0000000..4730e3d
--- /dev/null
+++ b/src/squeue/squeue.h
@@ -0,0 +1,27 @@
+struct squeue_t {
+ int shmid;
+ int mode;
+ char *pool;
+ /* pointers */
+ int head_idx;
+ int squeue_idx;
+ /* counters */
+ int squeue_locks;
+ int squeue_lost;
+ int squeue_oops;
+ int squeue_pops;
+};
+
+
+#define Q_OPEN 0
+#define Q_CREAT 1
+#define Q_WAIT 2
+
+int squeue_release(const char *file);
+struct squeue_t *squeue_open(const char *file, int init);
+int squeue_close(struct squeue_t *q);
+void squeue_free(struct squeue_t *q);
+int squeue_push(struct squeue_t *q, const char *str, int lock);
+int squeue_pop(struct squeue_t *q);
+char *squeue_get(struct squeue_t *q, int lock);
+void squeue_stats(struct squeue_t *q);
diff --git a/src/squeue/squeue.vapi b/src/squeue/squeue.vapi
new file mode 100644
index 0000000..b8d82d4
--- /dev/null
+++ b/src/squeue/squeue.vapi
@@ -0,0 +1,43 @@
+using GLib;
+
+[CCode (lower_case_cprefix = "squeue_", cheader_filename = "squeue.h")]
+namespace SQueues {
+ [CCode (cname = "struct squeue_t", free_function = "squeue_free")]
+ public struct SQueue {
+ int shmid;
+ int mode;
+ char *pool;
+ /* pointers */
+ int head_idx;
+ int queue_idx;
+ /* counters */
+ int locks;
+ int lost;
+ int oops;
+ int pops;
+ [CCode (cname = "squeue_open")]
+ public static SQueue* open(string file, int mode);
+ [CCode (cname = "squeue_push")]
+ public int push(string msg, int l);
+ [CCode (cname = "squeue_get")]
+ public weak string get(int l);
+ [CCode (cname = "squeue_pop")]
+ public int pop();
+ [CCode (cname = "squeue_stats")]
+ public int stats();
+ [CCode (cname = "squeue_close")]
+ public int close();
+ [CCode (cname = "squeue_free")]
+ public int free();
+ [CCode (cname = "squeue_release")]
+ public static int release(string file);
+
+ }
+
+ [CCode (cprefix = "Q_", cheader_fileneme = "squeue.h")]
+ public enum SQueueMode {
+ OPEN = 0,
+ CREAT = 1,
+ WAIT = 2
+ }
+}