diff options
author | pancake <pancake@dazo> | 2008-03-06 17:58:06 +0100 |
---|---|---|
committer | pancake <pancake@dazo> | 2008-03-06 17:58:06 +0100 |
commit | 83c25d7eb267f866968c7806c4afacf00fdfead5 (patch) | |
tree | 9873f0adc0142b9131cbbf0b6d1d5070a1b1823e | |
parent | 2ddb2923c68d023f9733fb82bb8d28140ea5b695 (diff) | |
download | 0xFFFF-83c25d7eb267f866968c7806c4afacf00fdfead5.tar.bz2 |
* Initial working version of the flash gui - Renamed to goxf - Needs 'sudo' to be enabled to the user without password - Identify and ban piece files while including them in the list - Support for flashing multiple piece files - progressbar and warn/error messages handled - Supports reboot mobo command
* Make qmode be functional
* Lot of hardcore fixups on squeue_open
- Should work now everywhere fine asumid UID 1000 as allowed user
- Reduce timeouts
- Add push2 method
-rw-r--r-- | src/fpid.c | 26 | ||||
-rw-r--r-- | src/gui/Makefile | 2 | ||||
-rw-r--r-- | src/gui/extras.vapi | 10 | ||||
-rw-r--r-- | src/gui/gui.gtkaml | 175 | ||||
-rw-r--r-- | src/main.c | 18 | ||||
-rw-r--r-- | src/main.h | 3 | ||||
-rw-r--r-- | src/os.h | 9 | ||||
-rw-r--r-- | src/qmode.c | 83 | ||||
-rw-r--r-- | src/query.c | 48 | ||||
-rw-r--r-- | src/squeue/squeue.c | 76 | ||||
-rw-r--r-- | src/squeue/squeue.h | 1 | ||||
-rw-r--r-- | src/squeue/squeue.vapi | 2 | ||||
-rw-r--r-- | src/utils.c | 30 |
13 files changed, 372 insertions, 111 deletions
@@ -20,6 +20,29 @@ #include <stdio.h> #include <string.h> +/* global structs */ +char *pieces[] = { + "xloader", // xloader.bin + "2nd", // 2nd + "secondary", // secondary.bin + "kernel", // zImage + "initfs", // jffs'd initfs + "rootfs", // 80mB of blob + "omap-nand", // 8kB of food for the nand + "fiasco", // FIASCO IMAGE + NULL +}; + +long fpid_size(const char *filename) +{ + long sz; + FILE *fd = fopen(filename, "r"); + fseek(fd, 0, SEEK_END); + sz = ftell(fd); + fclose(fd); + return sz; +} + const char *fpid_file(const char *filename) { FILE *fd; @@ -45,6 +68,9 @@ const char *fpid_file(const char *filename) size = ftell(fd); fclose(fd); + if (!memcmp(b, "\xb4", 1)) + return pieces[PIECE_FIASCO]; + else if (!memcmp(b+0x34, "2NDAPE", 6)) return pieces[PIECE_2ND]; else diff --git a/src/gui/Makefile b/src/gui/Makefile index 661bf66..58d9bc2 100644 --- a/src/gui/Makefile +++ b/src/gui/Makefile @@ -1,5 +1,5 @@ all: - gtkamlc --Xcc=-I../squeue ../squeue/squeue.c ../squeue/squeue.vapi gui.gtkaml --pkg gtk+-2.0 -o a.out + gtkamlc --save-temps --Xcc=-I../squeue ../squeue/squeue.c ../fpid.c ../squeue/squeue.vapi gui.gtkaml extras.vapi --pkg gtk+-2.0 -o goxf test: valac --save-temps --Xcc=-I.. squeue.vapi test.vala ../squeue.c -o v diff --git a/src/gui/extras.vapi b/src/gui/extras.vapi new file mode 100644 index 0000000..d8f2ddc --- /dev/null +++ b/src/gui/extras.vapi @@ -0,0 +1,10 @@ +namespace Extras { + public class External { + [CCode (cname = "system")] + public static int system(string cmd); + [CCode (cname = "fpid_file")] + public static string fpid_file(string file); + [CCode (cname = "fpid_size")] + public static long fpid_size(string file); + } +} diff --git a/src/gui/gui.gtkaml b/src/gui/gui.gtkaml index 8094da2..43ba5ca 100644 --- a/src/gui/gui.gtkaml +++ b/src/gui/gui.gtkaml @@ -6,8 +6,14 @@ --> -<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}"> +<Window xmlns="Gtk" + xmlns:GLib="GLib" + xmlns:Extras="Extras" + xmlns:SQueues="SQueues" + 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"> @@ -22,6 +28,17 @@ </MenuItem> <!-- Help menu --> + <MenuItem label="_Target" with-mnemonic="true"> + <submenu> + <Menu> + <ImageMenuItem stock-id="gtk-connect" activate="{OnConnect}"/> + <ImageMenuItem stock-id="gtk-info" activate="{OnGetInformation}"/> + <ImageMenuItem label="Reset" activate="{OnReset}"/> + </Menu> + </submenu> + </MenuItem> + + <!-- Help menu --> <MenuItem label="_Help" with-mnemonic="true"> <submenu> <Menu> @@ -38,33 +55,36 @@ </TreeView> </ScrolledWindow> - <ProgressBar class:private="pb" expand="false" /> </VBox> <VBox expand="false" border-width="3" spacing="3"> + <Button label="gtk-connect" use-stock="true" expand="false" clicked="{OnConnect}"/> + <Button label="gtk-info" use-stock="true" expand="false" clicked="{OnGetInformation}"/> + <Label label="" /> +<!-- <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="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"/> + <Button label="gtk-media-record" use-stock="true" expand="false" clicked="{OnFileFlashEvent}"/> </VBox> </HBox> + <ProgressBar class:private="pb" expand="false" /> - <Statusbar expand="false"/> + <!-- <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" + program-name="0xFFFF" version="0.3.9" 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 (); @@ -75,19 +95,49 @@ private void doCloseApplication () Gtk.main_quit (); } +private void OnReset() +{ + q->push("reset:device", 1); +} + +private void OnFileFlashEvent() +{ + ListStore ls = (ListStore)tv.get_model(); + weak string str; + TreeIter iter; + + int n = ls.iter_n_children(null); + if (n >0) { + if (showYesNo("Do you want to flash these files?")) { + ls.get_iter_first(out iter); + do { + ls.get(iter, 2, out str, -1); + //stdout.printf("polla:%s\n", str); + q->push2("flash", str, 1); + } while(ls.iter_next(ref iter)); + } + } else { + showMessage("No files selected", MessageType.ERROR); + } +} + private void OnFileOpenEvent () { FileChooserDialog fc = new FileChooserDialog("Select file to open", - this, - FileChooserAction.OPEN, - "gtk-cancel",ResponseType.CANCEL, - "gtk-open",ResponseType.ACCEPT); - + 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 ()); + if (resp == ResponseType.ACCEPT) { + string file = fc.get_filename(); + string *type = External.fpid_file(file); + string size = "%ld".printf(External.fpid_size(file)); + if (type == null) { + showMessage("Invalid file type", MessageType.ERROR); + } else { + add_file(type, size, file); + } } fc.destroy (); } @@ -95,20 +145,28 @@ private void OnFileOpenEvent () public bool loadFile( string filename ) { int err = 0; - try - { + try { string contents; int length; FileUtils.get_contents (filename, out contents, out length); //textview1.buffer.set_text (contents, length); - } - catch(Error e) - { + } 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 bool showYesNo(string s) +{ + MessageDialog md = new MessageDialog (this, + DialogFlags.DESTROY_WITH_PARENT, + MessageType.QUESTION, ButtonsType.YES_NO, s); + int ret = md.run (); + md.destroy (); + + return ret==ResponseType.YES; +} + public void showMessage(string s, MessageType mt) { MessageDialog md = new MessageDialog (this, @@ -144,9 +202,11 @@ private void OnFileNewEvent () private void OnQuitEvent () { doCloseApplication(); + External.system("sudo pkill 0xFFFF"); + // TODO: send message to gracefully kill 0xFFFF + // TODO: handle ^C when flashing } - public void list_clear() { ((ListStore)tv.model).clear(); @@ -156,28 +216,31 @@ public void list_del() { TreeIter iter; TreeModel model; - string str = ""; + weak string str = ""; TreeSelection sel = tv.get_selection(); if (sel.count_selected_rows() == 1) { sel.get_selected(out model, out iter); + //((ListStore)tv.model)).get(ref iter, 2, out str, -1); + + //stdout.printf("NAME IS: "+str); ((ListStore)tv.model).remove(iter); } //return str; } -public void add_file(string file) +public void add_file(string type, string size, 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); + listmodel.set (iter, 0, type, 1, size, 2, file, -1); } -public static void setup_treeview (Gtk.TreeView view) { - +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 */ @@ -191,22 +254,40 @@ public static void setup_treeview (Gtk.TreeView view) { 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); +// 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); - } + // 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); + stdout.printf("[<] msg received: %s\n", msg); + string[] foo = msg.split(":",2); + if (foo[1] != null) { + switch(foo[0]) { + case "bar": + viewer.pb.fraction = foo[1].to_int() / 100; + viewer.pb.text = foo[1]+"%"; + break; + case "error": + viewer.showMessage(foo[1], MessageType.ERROR); + break; + case "info": + viewer.showMessage(foo[1], MessageType.INFO); + break; + default: + stderr.printf("[E] Unknown message type\n"); + break; + } + //viewer.showMessage(msg, MessageType.INFO); + } p->pop(); } return true; @@ -217,10 +298,20 @@ static SQueue *p = null; private void OnGetInformation() { -stdout.printf("chking\n"); - msg("foo"); + msg("info:device"); } +private void OnConnect() +{ + //msg("connect:device"); + External.system("sudo pkill 0xFFFF"); + External.system("sudo ../0xFFFF -Q &"); + p->close(); + q->close(); + p = q = null; +} + + private bool chk_queues() { if (p == null) @@ -260,7 +351,7 @@ static int main (string[] args) 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)); + Timeout.add(200, (SourceFunc)(readFunc)); Gtk.main (); return 0; } @@ -23,10 +23,6 @@ #include <stdlib.h> #include <getopt.h> -#if HAVE_SQUEUE -#include "squeue/squeue.h" -#endif - /* global pr0n */ #if HAVE_USB #include <usb.h> @@ -47,18 +43,6 @@ int unpack = 0; int qmode = 0; int info = 0; -/* global structs */ -char *pieces[] = { - "xloader", // xloader.bin - "2nd", // 2nd - "secondary", // secondary.bin - "kernel", // zImage - "initfs", // jffs'd initfs - "rootfs", // 80mB of blob - "omap-nand", // 8kB of food for the nand - NULL -}; - char *modes[]={ "host", "peripheral", @@ -331,7 +315,7 @@ int main(int argc, char **argv) && (rd_flags == -1) && (rd_mode == -1) && (info == 0) - && (moboreboot == 0) + && (moboreboot == 0) && (usb_mode == -1) && (root_device == -1)) { @@ -6,6 +6,8 @@ #include "nolo.h" #include "os.h" +extern char strbuf[1024]; + #define _FILE_OFFSET_BITS 64 #define _GNU_SOURCE @@ -82,6 +84,7 @@ enum { PIECE_INITFS, PIECE_ROOTFS, PIECE_OMAPNAND, + PIECE_FIASCO, PIECE_LAST }; @@ -7,4 +7,13 @@ #define HAVE_SQUEUE 0 #endif +#if HAVE_SQUEUE + +#include "squeue/squeue.h" +extern int qmode; +extern struct squeue_t *p; + #endif + +#endif + diff --git a/src/qmode.c b/src/qmode.c index 7343b2b..3aa73fa 100644 --- a/src/qmode.c +++ b/src/qmode.c @@ -19,8 +19,8 @@ #include "main.h" #include "os.h" #include <stdio.h> +#include <signal.h> #if HAVE_SQUEUE -#include "squeue/squeue.h" struct squeue_t *q; struct squeue_t *p; @@ -35,8 +35,55 @@ int dofork() void process_message(char *msg) { - squeue_push(p, "nice shot!", 0); - printf("childa (%s)\n", msg); + char *str; + char *arg; + int c; + if (msg == NULL) + return; + printf("[x] (%s)\n", msg); + str = strdup(msg); + arg = strchr(str, ':'); + if (c!=NULL) { + arg[0]='\0'; + arg = arg +1; + if (!strcmp(str, "flash")) { + char buf[1024]; + char *type = fpid_file(arg); + if (type == NULL) { + squeue_push2(p, "error", "Unknown piece format", 1); + } else { + flash_image(arg, type, NULL); + } + } else + if (!strcmp(str, "reset")) { + if (reboot_board() == 0) { + squeue_push2(p,"info", "Device reboots", 1); + } else + squeue_push2(p,"error", "Cannot reboot device", 1); + } else + if (!strcmp(str, "info")) { + get_rd_flags(); + squeue_push2(p, "info", strbuf, 1); + get_nolo_version(); + squeue_push2(p, "info", strbuf, 1); + get_usb_mode(); + squeue_push2(p, "info", strbuf, 1); + } else + squeue_push2(p, "error", "invalid command", 0); + } else { + squeue_push2(p, "error", "invalid command format", 0); + } + free(str); +} + +static void cc() +{ + squeue_close(p); + squeue_close(q); + printf("pipes closed\n"); + squeue_release("/tmp/0xFFFF.1"); + squeue_release("/tmp/0xFFFF.2"); + exit(1); } int queue_mode() @@ -44,6 +91,8 @@ int queue_mode() int pid = 0; char *msg; + signal(SIGINT, cc); + pid = dofork(); if (pid) { wait(pid); @@ -55,21 +104,33 @@ int queue_mode() fprintf(stderr, "Cannot open queue files\n"); return 0; } + chmod("/tmp/0xFFFF.1", 0666); + chmod("/tmp/0xFFFF.2", 0666); 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); + do { +#if HAVE_USB + if (connect_via_usb()) { + fprintf(stderr, "Cannot connect to device. It is possibly not in boot stage.\n"); + squeue_push2(p, "error", "Cannot connect to the device", 1); + return 0; } - } +#endif + 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); + } + } + printf("Connection restarted\n"); + } while (1); } } return 0; diff --git a/src/query.c b/src/query.c index 6709fd2..404a60b 100644 --- a/src/query.c +++ b/src/query.c @@ -24,6 +24,8 @@ #include <stdlib.h> #include <usb.h> +char strbuf[1024]; + /* wait for status = 0 */ int get_status() { @@ -76,7 +78,8 @@ int get_usb_mode() return -1; } - printf("Device's USB mode is '%s'\n", (mode) ? "host" : "client"); + sprintf(strbuf, "Device's USB mode is '%s'\n", (mode) ? "host" : "client"); + printf(strbuf); return 0; } @@ -160,11 +163,12 @@ int get_rd_mode() { char isrd = 1; + strbuf[0]='\0'; if (usb_control_msg(dev, CMD_QUERY, NOLO_GET_RDFLAGS, 0, 0, (char *)&isrd, 1, 2000) == -1) { fprintf(stderr, "Cannot query rd mode.\n"); return -1; } - printf("RD mode is: %s\n", isrd?"on":"off"); + sprintf(strbuf, "RD mode is: %s\n", isrd?"on":"off"); return isrd; } @@ -173,16 +177,19 @@ int get_root_device() { unsigned char opcode; + strbuf[0] = '\0'; if (usb_control_msg(dev, CMD_QUERY, NOLO_GET_RDFLAGS, 0, 1, (char *)&opcode, 1, 2000) < 0) { fprintf(stderr, "Cannot query root device\n"); return -1; } if (opcode>2) { // use sizeof || enum - printf("Invalid root device received from the device '%d'.\n", opcode); + fprintf(stderr, "Invalid root device received from the device '%d'.\n", opcode); + return -1; } - printf("Root device is: %s\n", root_devices[opcode]); + sprintf(strbuf, "Root device is: %s\n", root_devices[opcode]); + printf(strbuf); return 0; } @@ -286,15 +293,23 @@ int get_rd_flags() if (usb_control_msg(dev, CMD_QUERY, NOLO_GET_RDFLAGS, 0, 3, (void *) &flags, sizeof(flags), 2000) == -1) { fprintf(stderr, "Cannot get rd flags\n"); + sprintf(strbuf, "error: Cannot read rd flags\n"); return -1; } - printf("Current rd flag setting:\n"); - printf("disable OMAP watchdog : %s\n", (flags & 0x02) ? "set" : "not set"); - printf("disable RETU watchdog : %s\n", (flags & 0x04) ? "set" : "not set"); - printf("disable lifeguard reset: %s\n", (flags & 0x08) ? "set" : "not set"); - printf("enable serial console : %s\n", (flags & 0x10) ? "set" : "not set"); - printf("disable USB timeout : %s\n", (flags & 0x20) ? "set" : "not set"); + sprintf(strbuf, + "Current rd flag setting:\n" + "disable OMAP watchdog : %s\n" + "disable RETU watchdog : %s\n" + "disable lifeguard reset: %s\n" + "enable serial console : %s\n" + "disable USB timeout : %s\n" + , (flags & 0x02) ? "set" : "not set" + , (flags & 0x04) ? "set" : "not set" + , (flags & 0x08) ? "set" : "not set" + , (flags & 0x10) ? "set" : "not set" + , (flags & 0x20) ? "set" : "not set"); + printf(strbuf); return 0; } @@ -306,10 +321,12 @@ int get_nolo_version() //if (usb_control_msg(dev, CMD_QUERY, 3, 0, 1, (char *)&version, 4 , 2000) < 0) { if (usb_control_msg(dev, CMD_QUERY, NOLO_GET_VERSION, 0, 0, (char *)&version, 4 , 2000) < 0) { fprintf(stderr, "Cannot query nolo version. Old bootloader version?\n"); - exit(1); + sprintf(strbuf, "error: Cannot query nolo version. Old bootloader?"); + return -1; } - printf("NOLO Version %d.%d.%d\n", + sprintf(strbuf, + "NOLO Version %d.%d.%d\n", version >> 20 & 15, version >> 16 & 15, version >> 8 & 255); @@ -320,6 +337,7 @@ int get_nolo_version() return 0; } + int get_sw_version() { int ret; @@ -337,7 +355,11 @@ int get_sw_version() fprintf(stderr, "error: b0rken swversion read!\n"); return 0; } - printf("SWVERSION GOT: %s\n", bytes); //???+strlen(bytes)+1)); + if (bytes[0]) { + sprintf(strbuf, "Software Version: %s\n", bytes); + printf("Software Version: %s\n", bytes); //???+strlen(bytes)+1)); + } else + printf("No software version detected\n"); return 1; } diff --git a/src/squeue/squeue.c b/src/squeue/squeue.c index 0386784..0d134f0 100644 --- a/src/squeue/squeue.c +++ b/src/squeue/squeue.c @@ -1,5 +1,6 @@ #include "squeue.h" #include <unistd.h> +#include <errno.h> #include <stdlib.h> #include <sys/ipc.h> #include <signal.h> @@ -10,7 +11,7 @@ #include <string.h> #define POOL_SIZE ITEM_MAX*ITEM_SIZE -#define ITEM_SIZE 80 +#define ITEM_SIZE 512 #define ITEM_MAX 10 int squeue_release(const char *file) @@ -29,36 +30,63 @@ int squeue_release(const char *file) return shmctl(shmid, IPC_RMID,NULL); } +extern int errno; struct squeue_t *squeue_open(const char *file, int mode) { struct squeue_t *q; char *pool; int shmid; - key_t k = ftok(file, 0xa3); + key_t k; + + k = ftok(file, 0x34); + if (k == -1) { + perror("ftok"); + squeue_release(file); + close(creat(file, 0666)); + chmod(file, 0666); + k = ftok(file, 0xa3); + if (k == -1) { + perror("ftok"); + return NULL; + } + } _retry: - shmid = shmget(k, POOL_SIZE, 0666); + shmid = shmget(k, POOL_SIZE, 0666|(mode==Q_CREAT)?IPC_CREAT:0); 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)); + perror("shmget1"); + shmid = shmget(k, POOL_SIZE, 0666|((mode==Q_CREAT)?IPC_CREAT:0)); if (shmid == -1) { - if (mode == Q_WAIT) { - usleep(200); - goto _retry; + perror("shmget2"); + if (errno == EEXIST) + shmid = shmget(k, POOL_SIZE, 0666 |IPC_CREAT); + + if (shmid == -1) { + if (mode == Q_WAIT) { + usleep(100); + goto _retry; + } + perror("shmget"); + return NULL; } - perror("shmget"); - return NULL; } } if (mode == Q_WAIT) mode = Q_OPEN; - pool = shmat(shmid, NULL, k); + /* fix perms */ + if (mode == Q_CREAT) { + struct shmid_ds sd; + shmctl(shmid, IPC_STAT, &sd); + sd.shm_perm.uid = 1000; + sd.shm_perm.gid = 1000; + sd.shm_perm.mode = sd.shm_perm.mode|0666; + shmctl(shmid, IPC_SET, &sd); + } + + pool = shmat(shmid, NULL, 0); if (((int)pool) == -1) { - perror("shmat\n"); + perror("shmat"); return NULL; } @@ -113,7 +141,7 @@ int squeue_push(struct squeue_t *q, const char *str, int lock) printf("buffer is full\n"); return -1; } - usleep(200); + usleep(100); } q->squeue_idx = 0; } @@ -132,6 +160,18 @@ int squeue_push(struct squeue_t *q, const char *str, int lock) return 0; } +int squeue_push2(struct squeue_t *q, const char *head, const char *str, int lock) +{ + int ret; + char *buf = malloc(strlen(head) + strlen(str) + 2); + strcpy(buf, head); + strcat(buf, ":"); + strcat(buf, str); + ret = squeue_push(q, buf, lock); + free(buf); + return ret; +} + int squeue_pop(struct squeue_t *q) { int i; @@ -175,7 +215,7 @@ char *squeue_get(struct squeue_t *q, int lock) return q->pool+i; } if (lock) - usleep(500); + usleep(100); } while (lock); return NULL; } @@ -226,7 +266,7 @@ int main() printf("get: (%s)\n", uh); squeue_pop(q); } - usleep(200); + usleep(100); } squeue_close(q); } else { diff --git a/src/squeue/squeue.h b/src/squeue/squeue.h index 4730e3d..e027d51 100644 --- a/src/squeue/squeue.h +++ b/src/squeue/squeue.h @@ -22,6 +22,7 @@ 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_push2(struct squeue_t *q, const char *head, 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 index b8d82d4..0f66713 100644 --- a/src/squeue/squeue.vapi +++ b/src/squeue/squeue.vapi @@ -19,6 +19,8 @@ namespace SQueues { public static SQueue* open(string file, int mode); [CCode (cname = "squeue_push")] public int push(string msg, int l); + [CCode (cname = "squeue_push2")] + public int push2(string cmd, string msg, int l); [CCode (cname = "squeue_get")] public weak string get(int l); [CCode (cname = "squeue_pop")] diff --git a/src/utils.c b/src/utils.c index 4803a50..2f4efbb 100644 --- a/src/utils.c +++ b/src/utils.c @@ -42,16 +42,28 @@ void progressbar(unsigned long long part, unsigned long long total) int pc; int tmp, cols = 80; + /* percentage calculation */ pc = (int)(part*100/total); - (pc<0)?pc=0:(pc>100)?pc=100:0; - printf("\e[K %3d%% [", pc); - if (columns) - cols = atoi(columns); - cols-=15; - for(tmp=cols*pc/100;tmp;tmp--) printf("#"); - for(tmp=cols-(cols*pc/100);tmp;tmp--) printf("-"); - printf("]\r"); - fflush(stdout); + (pc<0)?pc=0:(pc>100)?pc=100:0; + +#if HAVE_SQUEUE + if (qmode) { + char msg[128]; + sprintf(msg, "%d%%", pc); + squeue_push2(p, "bar", msg, 0); + } else { +#endif + printf("\e[K %3d%% [", pc); + if (columns) + cols = atoi(columns); + cols-=15; + for(tmp=cols*pc/100;tmp;tmp--) printf("#"); + for(tmp=cols-(cols*pc/100);tmp;tmp--) printf("-"); + printf("]\r"); + fflush(stdout); +#if HAVE_SQUEUE + } +#endif } void eprintf(const char *format, ...) |