tAdd shutdown() for clean exit - ratox - FIFO based tox client
 (DIR) Log
 (DIR) Files
 (DIR) Refs
 (DIR) README
 (DIR) LICENSE
       ---
 (DIR) commit 9f234f9156bd2687a30f99ad66f9861154ec7446
 (DIR) parent 7c54e12d5120fe3c9dc037064977d01493de0d74
 (HTM) Author: FRIGN <dev@frign.de>
       Date:   Sun, 21 Sep 2014 10:26:17 +0100
       
       Add shutdown() for clean exit
       
       This also sends a broadcast to all friends you went offline,
       leading to an immediate event-feedback.
       
       Diffstat:
         M ratox.c                             |      66 ++++++++++++++++++++++++++++++-
       
       1 file changed, 65 insertions(+), 1 deletion(-)
       ---
 (DIR) diff --git a/ratox.c b/ratox.c
       t@@ -8,6 +8,7 @@
        #include <errno.h>
        #include <fcntl.h>
        #include <limits.h>
       +#include <signal.h>
        #include <stdarg.h>
        #include <stdint.h>
        #include <stdio.h>
       t@@ -158,6 +159,7 @@ static TAILQ_HEAD(friendhead, friend) friendhead = TAILQ_HEAD_INITIALIZER(friend
        static TAILQ_HEAD(reqhead, request) reqhead = TAILQ_HEAD_INITIALIZER(reqhead);
        
        static Tox *tox;
       +static int running = 1;
        
        static void printrat(void);
        static void printout(const char *, ...);
       t@@ -181,6 +183,8 @@ static void str2id(char *, uint8_t *);
        static struct friend *friendcreate(int32_t);
        static void friendload(void);
        static void loop(void);
       +static void initshutdown(int);
       +static void shutdown(void);
        
        static void
        printrat(void)
       t@@ -965,7 +969,7 @@ loop(void)
                t0 = time(NULL);
                printout("Connecting to DHT...\n");
                toxconnect();
       -        while (1) {
       +        while (running) {
                        if (tox_isconnected(tox) == 1) {
                                if (connected == 0) {
                                        printout("Connected to DHT\n");
       t@@ -1123,13 +1127,73 @@ loop(void)
                }
        }
        
       +static void
       +initshutdown(int sig)
       +{
       +        printout("Shutting down...\n");
       +        running = 0;
       +}
       +
       +static void
       +shutdown(void)
       +{
       +        int i, m;
       +        struct friend *f, *ftmp;
       +        struct request *r, *rtmp;
       +
       +        tox_kill(tox);
       +
       +        /* friends */
       +        for (f = TAILQ_FIRST(&friendhead); f; f = ftmp) {
       +                ftmp = TAILQ_NEXT(f, entry);
       +
       +                for (i = 0; i < LEN(ffiles); i++) {
       +                        unlinkat(f->dirfd, ffiles[i].name, 0);
       +                        close(f->fd[i]);
       +                }
       +                rmdir(f->idstr);
       +                /* T0D0: cancel transmissions */
       +                TAILQ_REMOVE(&friendhead, f, entry);
       +        }
       +
       +        /* requests */
       +        for (r = TAILQ_FIRST(&reqhead); r; r = rtmp) {
       +                rtmp = TAILQ_NEXT(r, entry);
       +
       +                unlinkat(gslots[REQUEST].fd[OUT], r->idstr, 0);
       +                close(r->fd);
       +                TAILQ_REMOVE(&reqhead, r, entry);
       +                free(r->msgstr);
       +                free(r);
       +        }
       +
       +        /* global files and slots */
       +        for (i = 0; i < LEN(gslots); i++) {
       +                for (m = 0; m < LEN(gfiles); m++) {
       +                        unlinkat(gslots[i].dirfd, gfiles[m].name,
       +                                 (gslots[i].outtype == FOLDER && m == OUT)
       +                                 ? AT_REMOVEDIR : 0);
       +                        close(gslots[i].fd[m]);
       +                }
       +                rmdir(gslots[i].name);
       +        }
       +        unlink("id");
       +}
       +
        int
        main(int argc, char *argv[])
        {
       +        signal(SIGHUP, initshutdown);
       +        signal(SIGINT, initshutdown);
       +        signal(SIGQUIT, initshutdown);
       +        signal(SIGABRT, initshutdown);
       +        signal(SIGTERM, initshutdown);
       +
                printrat();
                toxinit();
                localinit();
                friendload();
                loop();
       +        shutdown();
                return EXIT_SUCCESS;
        }