* 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
This commit is contained in:
1 parent
32a59f4279
commit
2ddb2923c6
11 files changed
+714
-7
No files matched your search
@@ -1,4 +1,4 @@
|
|||||||
VERSION=0.3.2
|
VERSION=0.3.9
|
||||||
PREFIX=/usr
|
PREFIX=/usr
|
||||||
|
|
||||||
# NetBSD stuff
|
# NetBSD stuff
|
||||||
|
|||||||
+2
-1
@@ -1,6 +1,7 @@
|
|||||||
include ../config.mk
|
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+=hash.o fpid.o query.o pieces.o utils.o devices.o console.o
|
||||||
|
OBJ+=squeue/squeue.o
|
||||||
BIN=0xFFFF
|
BIN=0xFFFF
|
||||||
#LIBS=`${HAVE_USB} && echo -- '-lusb'`
|
#LIBS=`${HAVE_USB} && echo -- '-lusb'`
|
||||||
LIBS=`if [ "${HAVE_USB}" = 1 ]; then echo '-lusb'; fi`
|
LIBS=`if [ "${HAVE_USB}" = 1 ]; then echo '-lusb'; fi`
|
||||||
|
|||||||
@@ -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
|
||||||
@@ -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>
|
||||||
+21
-5
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* 0xFFFF - Open Free Fiasco Firmware Flasher
|
* 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
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
@@ -23,6 +23,10 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <getopt.h>
|
#include <getopt.h>
|
||||||
|
|
||||||
|
#if HAVE_SQUEUE
|
||||||
|
#include "squeue/squeue.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
/* global pr0n */
|
/* global pr0n */
|
||||||
#if HAVE_USB
|
#if HAVE_USB
|
||||||
#include <usb.h>
|
#include <usb.h>
|
||||||
@@ -40,6 +44,7 @@ int verbose = 0;
|
|||||||
int identify = 0;
|
int identify = 0;
|
||||||
int moboreboot = 0;
|
int moboreboot = 0;
|
||||||
int unpack = 0;
|
int unpack = 0;
|
||||||
|
int qmode = 0;
|
||||||
int info = 0;
|
int info = 0;
|
||||||
|
|
||||||
/* global structs */
|
/* global structs */
|
||||||
@@ -90,6 +95,9 @@ void show_usage()
|
|||||||
printf(" -r [0|1] disable/enable R&D mode\n");
|
printf(" -r [0|1] disable/enable R&D mode\n");
|
||||||
printf(" -R reboot the omap board\n");
|
printf(" -R reboot the omap board\n");
|
||||||
printf(" -U [0|1] disable/enable the usb host mode\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
|
#endif
|
||||||
printf("Local stuff:\n");
|
printf("Local stuff:\n");
|
||||||
printf(" -s [serial] serial port console (minicom like terminal)\n");
|
printf(" -s [serial] serial port console (minicom like terminal)\n");
|
||||||
@@ -222,7 +230,7 @@ int main(int argc, char **argv)
|
|||||||
{
|
{
|
||||||
int c;
|
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) {
|
switch(c) {
|
||||||
case 'H':
|
case 'H':
|
||||||
printf("xorpair: %04x\n", do_hash_file(optarg));
|
printf("xorpair: %04x\n", do_hash_file(optarg));
|
||||||
@@ -286,6 +294,9 @@ int main(int argc, char **argv)
|
|||||||
fiasco_image = optarg;
|
fiasco_image = optarg;
|
||||||
unpack = 1;
|
unpack = 1;
|
||||||
break;
|
break;
|
||||||
|
case 'Q':
|
||||||
|
qmode = 1;
|
||||||
|
break;
|
||||||
case 'P':
|
case 'P':
|
||||||
return fiasco_pack(optind, argv);
|
return fiasco_pack(optind, argv);
|
||||||
case 'I':
|
case 'I':
|
||||||
@@ -306,6 +317,9 @@ int main(int argc, char **argv)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (qmode)
|
||||||
|
return queue_mode();
|
||||||
|
|
||||||
if (identify)
|
if (identify)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
@@ -321,9 +335,11 @@ int main(int argc, char **argv)
|
|||||||
&& (usb_mode == -1)
|
&& (usb_mode == -1)
|
||||||
&& (root_device == -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("# The Free Fiasco Firmware Flasher v"VERSION"\n"
|
||||||
printf(" [-s serial-dev] [-u fiasco-image] [-U 0|1] | [-P new-fiasco] [piece1] [2] ..\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;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
|
|
||||||
#include "hash.h"
|
#include "hash.h"
|
||||||
#include "nolo.h"
|
#include "nolo.h"
|
||||||
|
#include "os.h"
|
||||||
|
|
||||||
#define _FILE_OFFSET_BITS 64
|
#define _FILE_OFFSET_BITS 64
|
||||||
#define _GNU_SOURCE
|
#define _GNU_SOURCE
|
||||||
@@ -11,6 +12,7 @@
|
|||||||
// Forward declaration for use in function arguments.
|
// Forward declaration for use in function arguments.
|
||||||
struct devices;
|
struct devices;
|
||||||
|
|
||||||
|
int queue_mode();
|
||||||
int reverse_extract_pieces(char *dir);
|
int reverse_extract_pieces(char *dir);
|
||||||
void flash_image(char *filename, char *piece, char *version);
|
void flash_image(char *filename, char *piece, char *version);
|
||||||
int fiasco_read_image(char *file);
|
int fiasco_read_image(char *file);
|
||||||
|
|||||||
@@ -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
|
||||||
+83
@@ -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
|
||||||
@@ -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
|
||||||
@@ -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);
|
||||||
@@ -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
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in new issue
Block a user