~benklop/+junk/lcdproc

« back to all changes in this revision

Viewing changes to clients/lcdexec/lcdexec.c

  • Committer: Bazaar Package Importer
  • Author(s): Jeremy Yoder (Launchpad)
  • Date: 2009-10-11 18:21:07 UTC
  • mfrom: (1.1.4 upstream)
  • Revision ID: james.westby@ubuntu.com-20091011182107-twnkyhv1f63lzq3o
Tags: 0.5.3-0ubuntu1
* New upstream version 0.5.3 (LP: #432669)
* Merge source patches from 0.5.2-3 
  - LCDd.conf: Change driver path
  - clients/lcdproc/machine_Linux.c: Change ifdef
* Add clients/examples/lcdident.pl to debian files 
* Updated debian/rules:
  - Cleaned up whitespace
  - Changed config.guess/config.sub lines 
* Added a delay to server/drivers/imonlcd.c for slower models
* Added dependency on autotools-dev to fix launchpad build issue 

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
2
 
 * lcdexec.c
3
 
 * This file is part of lcdexec, an LCDproc client.
 
1
/* \file clients/lcdexec/lcdexec.c
 
2
 * Main file for \lcdexec, the program starter in the LCDproc suite.
 
3
 */
 
4
 
 
5
/* This file is part of lcdexec, an LCDproc client.
4
6
 *
5
7
 * This file is released under the GNU General Public License. Refer to the
6
8
 * COPYING file distributed with this package.
7
9
 *
8
10
 * Copyright (c) 2002, Joris Robijn
9
 
 * Copyright (c) 2006, Peter Marschall
 
11
 *               2006-2008, Peter Marschall
10
12
 */
11
13
 
12
14
#include <stdio.h>
13
15
#include <unistd.h>
14
16
#include <string.h>
 
17
#include <strings.h>
 
18
#include <errno.h>
15
19
#include <sys/utsname.h>
 
20
#include <signal.h>
 
21
#include <time.h>
 
22
#include <sys/wait.h>
16
23
 
17
24
#include "getopt.h"
18
25
 
23
30
 
24
31
#include "menu.h"
25
32
 
 
33
 
26
34
#if !defined(SYSCONFDIR)
27
35
# define SYSCONFDIR     "/etc"
28
36
#endif
 
37
#if !defined(PIDFILEDIR)
 
38
# define PIDFILEDIR     "/var/run"
 
39
#endif
29
40
 
30
41
#define DEFAULT_CONFIGFILE      SYSCONFDIR "/lcdexec.conf"
 
42
#define DEFAULT_PIDFILE         PIDFILEDIR "/lcdexec.pid"
 
43
 
 
44
 
 
45
/** information about a process started by lcdexec */
 
46
typedef struct ProcInfo {
 
47
        struct ProcInfo *next;  /**< pointer to the next ProcInfo entry */
 
48
        const MenuEntry *cmd;   /**< pointer to the corresponding menu entry */
 
49
        pid_t pid;              /**< PID the process was started with */
 
50
        time_t starttime;       /**< start time of the process */
 
51
        time_t endtime;         /**< finishing time of the process */
 
52
        int status;             /**< exit status of the process */
 
53
        int feedback;           /**< what info to show to the user */
 
54
        int shown;              /**< tell if the info has been shown to the user */
 
55
} ProcInfo;
31
56
 
32
57
 
33
58
char * help_text =
34
59
"lcdexec - LCDproc client to execute commands from the LCDd menu\n"
35
60
"\n"
36
 
"Copyright (c) 2002, Joris Robijn, 2006 Peter Marschall.\n"
 
61
"Copyright (c) 2002, Joris Robijn, 2006-2008 Peter Marschall.\n"
37
62
"This program is released under the terms of the GNU General Public License.\n"
38
63
"\n"
39
64
"Usage: lcdexec [<options>]\n"
51
76
/* Variables set by config */
52
77
#define UNSET_INT -1
53
78
#define UNSET_STR "\01"
54
 
char * configfile = NULL;
55
 
char * address = NULL;
 
79
char *configfile = NULL;
 
80
char *address = NULL;
56
81
int port = UNSET_INT;
57
82
int foreground = FALSE;
58
83
static int report_level = UNSET_INT;
59
84
static int report_dest = UNSET_INT;
 
85
char *pidfile = NULL;
 
86
int pidfile_written = FALSE;
60
87
char *displayname = NULL;
61
88
char *default_shell = NULL;
62
89
 
63
 
MenuEntry *main_menu;
64
 
 
65
 
/* Other variables */
66
 
int sock = -1;
 
90
/* Other global variables */
 
91
MenuEntry *main_menu = NULL;    /**< pointer to the main menu */
 
92
ProcInfo *proc_queue = NULL;    /**< pointer to the list of executed processes */
 
93
 
 
94
int lcd_wid = 0;                /**< LCD display width reported by the server */
 
95
int lcd_hgt = 0;                /**< LCD display height reported by the server */
 
96
 
 
97
int sock = -1;                  /**< socket to connect to server */
 
98
 
 
99
int Quit = 0;                   /**< indicate end of main loop */
 
100
 
67
101
 
68
102
/* Function prototypes */
 
103
static void exit_program(int val);
 
104
static void sigchld_handler(int signal);
69
105
static int process_command_line(int argc, char **argv);
70
106
static int process_configfile(char * configfile);
71
107
static int connect_and_setup(void);
72
108
static int process_response(char *str);
73
109
static int exec_command(MenuEntry *cmd);
 
110
static int show_procinfo_msg(ProcInfo *p);
74
111
static int main_loop(void);
75
112
 
76
113
 
81
118
int main(int argc, char **argv)
82
119
{
83
120
        int error = 0;
 
121
        struct sigaction sa;
84
122
 
85
123
        CHAIN(error, process_command_line(argc, argv));
86
124
        if (configfile == NULL)
101
139
                if (daemon(1,1) != 0) {
102
140
                        report(RPT_ERR, "Error: daemonize failed");
103
141
                }
 
142
 
 
143
                if (pidfile != NULL) {
 
144
                        FILE *pidf = fopen(pidfile, "w");
 
145
 
 
146
                        if (pidf) {
 
147
                                fprintf(pidf, "%d\n", (int) getpid());
 
148
                                fclose(pidf);
 
149
                                pidfile_written = TRUE;
 
150
                        } else {
 
151
                                fprintf(stderr, "Error creating pidfile %s: %s\n",
 
152
                                        pidfile, strerror(errno));
 
153
                                return(EXIT_FAILURE);
 
154
                        }
 
155
                }
104
156
        }
105
157
 
 
158
        /* setup signal handlers for common signals */
 
159
        sigemptyset(&sa.sa_mask);
 
160
        sa.sa_flags = SA_RESTART;
 
161
        sa.sa_handler = exit_program;
 
162
        sigaction(SIGINT, &sa, NULL);   // Ctrl-C
 
163
        sigaction(SIGTERM, &sa, NULL);  // "regular" kill
 
164
        sigaction(SIGHUP, &sa, NULL);   // kill -HUP
 
165
        sigaction(SIGPIPE, &sa, NULL);  // write to closed socket
 
166
        sigaction(SIGKILL, &sa, NULL);  // kill -9 [cannot be trapped; but ...]
 
167
 
 
168
        /* setup signal handler for children to avoid zombies */
 
169
        sigemptyset(&sa.sa_mask);
 
170
        sa.sa_flags = SA_RESTART | SA_NOCLDSTOP;
 
171
        sa.sa_handler = sigchld_handler;
 
172
        sigaction(SIGCHLD, &sa, NULL);
 
173
 
106
174
        main_loop();
107
175
 
108
 
        return 0;
 
176
        exit_program(EXIT_SUCCESS);
 
177
}
 
178
 
 
179
 
 
180
static void exit_program(int val)
 
181
{
 
182
        //printf("exit program\n");
 
183
        Quit = 1;
 
184
        sock_close(sock);
 
185
        if ((foreground != TRUE) && (pidfile != NULL) && (pidfile_written == TRUE))
 
186
                unlink(pidfile);
 
187
        exit(val);
 
188
}
 
189
 
 
190
 
 
191
/* the grim reaper ;-) */
 
192
static void sigchld_handler(int signal)
 
193
{
 
194
        pid_t pid;
 
195
        int status;
 
196
 
 
197
        /* wait for the child that was signalled as finished */
 
198
        if ((pid = wait(&status)) != -1) {
 
199
                ProcInfo *p;
 
200
 
 
201
                /* fill the procinfo structure with the necessary information */
 
202
                for (p = proc_queue; p != NULL; p = p->next) {
 
203
                        if (p->pid == pid) {
 
204
                                p->status = status;
 
205
                                p->endtime = time(NULL);
 
206
                        }
 
207
                }       
 
208
        }
109
209
}
110
210
 
111
211
 
161
261
                        break;
162
262
                  case 'h':
163
263
                        fprintf(stderr, "%s", help_text);
164
 
                        exit(0);
 
264
                        exit(EXIT_SUCCESS);
165
265
                  case ':':
166
266
                        report(RPT_ERR, "Missing option argument for %c", optopt);
167
267
                        error = -1;
205
305
        if (foreground != TRUE) {
206
306
                foreground = config_get_bool(progname, "Foreground", 0, FALSE);
207
307
        }
 
308
        if (pidfile == NULL) {
 
309
                pidfile = strdup(config_get_string(progname, "PidFile", 0, DEFAULT_PIDFILE));
 
310
        }
208
311
 
209
312
        if ((tmp = config_get_string(progname, "DisplayName", 0, NULL)) != NULL)
210
313
                displayname = strdup(tmp);
273
376
 
274
377
static int process_response(char *str)
275
378
{
276
 
        char *argv[15];
 
379
        char *argv[20];
277
380
        int argc;
278
381
        char *str2 = strdup(str); /* get_args modifies str2 */
279
382
 
280
383
        report(RPT_DEBUG, "Server said: \"%s\"", str);
281
384
 
282
385
        /* Check what the server just said to us... */
283
 
        argc = get_args(argv, str2, 10);
 
386
        argc = get_args(argv, str2, sizeof(argv)/sizeof(argv[0]));
284
387
        if (argc < 1) {
285
388
                free(str2);
286
389
                return 0;
294
397
                        free(str2);
295
398
                        return -1;
296
399
                }
297
 
                if (strcmp(argv[1], "select") == 0) {
298
 
                        MenuEntry *exec;
 
400
                if ((strcmp(argv[1], "select") == 0) ||
 
401
                    (strcmp(argv[1], "leave") == 0)) {
 
402
                        MenuEntry *entry;
299
403
                        
300
404
                        if (argc < 3) {
301
405
                                report(RPT_WARNING, "Server gave invalid response");
303
407
                                return -1;
304
408
                        }
305
409
 
306
 
                        /* Find the id */
307
 
                        exec = menu_find_by_id(main_menu, atoi(argv[2]));
308
 
                        if (exec == NULL) {
309
 
                                report(RPT_WARNING, "Could not find the item id given by the server");
310
 
                                free(str2);
311
 
                                return -1;
312
 
                        }
313
 
                        /* The id has been found */
314
 
                        exec_command(exec);
 
410
                        /* Find the entry by id */
 
411
                        entry = menu_find_by_id(main_menu, atoi(argv[2]));
 
412
                        if (entry == NULL) {
 
413
                                report(RPT_WARNING, "Could not find the item id given by the server");
 
414
                                free(str2);
 
415
                                return -1;
 
416
                        }
 
417
 
 
418
                        /* The id has been found.
 
419
                         * We trigger on the following conditions:
 
420
                         * - command entry without args
 
421
                         * - last arg of a command entry with args */
 
422
                        if (((entry->type == MT_EXEC) && (entry->children == NULL)) ||
 
423
                            ((entry->type & MT_ARGUMENT) && (entry->next == NULL))) {
 
424
 
 
425
                                // last arg => get parent entry
 
426
                                if ((entry->type & MT_ARGUMENT) && (entry->next == NULL))
 
427
                                        entry = entry->parent;
 
428
 
 
429
                                if (entry->type == MT_EXEC)
 
430
                                        exec_command(entry);
 
431
                        }               
 
432
                }
 
433
                else if ((strcmp(argv[1], "plus") == 0) ||
 
434
                         (strcmp(argv[1], "minus") == 0) ||
 
435
                         (strcmp(argv[1], "update") == 0)) {
 
436
                        MenuEntry *entry;
 
437
                        
 
438
                        if (argc < 4) {
 
439
                                report(RPT_WARNING, "Server gave invalid response");
 
440
                                free(str2);
 
441
                                return -1;
 
442
                        }
 
443
 
 
444
                        /* Find the entry by id */
 
445
                        entry = menu_find_by_id(main_menu, atoi(argv[2]));
 
446
                        if (entry == NULL) {
 
447
                                report(RPT_WARNING, "Could not find the item id given by the server");
 
448
                                free(str2);
 
449
                                return -1;
 
450
                        }
 
451
 
 
452
                        switch (entry->type) {
 
453
                                case MT_ARG_SLIDER:
 
454
                                        entry->data.slider.value = atoi(argv[3]);
 
455
                                        break;
 
456
                                case MT_ARG_RING:
 
457
                                        entry->data.ring.value = atoi(argv[3]);
 
458
                                        break;
 
459
                                case MT_ARG_NUMERIC:
 
460
                                        entry->data.numeric.value = atoi(argv[3]);
 
461
                                        break;
 
462
                                case MT_ARG_ALPHA:
 
463
                                        entry->data.alpha.value = realloc(entry->data.alpha.value,
 
464
                                                                          strlen(argv[3]));
 
465
                                        strcpy(entry->data.alpha.value, argv[3]);
 
466
                                        break;
 
467
                                case MT_ARG_IP:
 
468
                                        entry->data.ip.value = realloc(entry->data.ip.value,
 
469
                                                                        strlen(argv[3]));
 
470
                                        strcpy(entry->data.ip.value, argv[3]);
 
471
                                        break;
 
472
                                case MT_ARG_CHECKBOX:
 
473
                                        if ((entry->data.checkbox.allow_gray) &&
 
474
                                            (strcasecmp(argv[3], "gray") == 0))
 
475
                                                entry->data.checkbox.value = 2;
 
476
                                        else if (strcasecmp(argv[3], "on") == 0)
 
477
                                                entry->data.checkbox.value = 1;
 
478
                                        else
 
479
                                                entry->data.checkbox.value = 0;
 
480
                                        break;
 
481
                                default:
 
482
                                        report(RPT_WARNING, "Illegal menu entry type for event");
 
483
                                        free(str2);
 
484
                                        return -1;
 
485
                        }
315
486
                }
316
487
                else {
317
488
                        ; /* Ignore other menuevents */
318
489
                }
319
490
        }
 
491
        else if (strcmp(argv[0], "connect") == 0) {
 
492
                int a;
 
493
 
 
494
                /* determine display height and width */
 
495
                for (a = 1; a < argc; a++) {
 
496
                        if (strcmp(argv[a], "wid") == 0)
 
497
                                lcd_wid = atoi(argv[++a]);
 
498
                        else if (strcmp(argv[a], "hgt") == 0)
 
499
                                lcd_hgt = atoi(argv[++a]);
 
500
                }
 
501
        }
 
502
        else if (strcmp(argv[0], "bye") == 0) {
 
503
                // TODO: make it better
 
504
                report(RPT_INFO, "Server said: \"%s\"", str);
 
505
                exit_program(EXIT_SUCCESS);
 
506
        }       
320
507
        else if (strcmp(argv[0], "huh?") == 0) {
321
508
                /* Report errors */
322
509
                report(RPT_WARNING, "Server said: \"%s\"", str);
334
521
        if ((cmd != NULL)  && (menu_command(cmd) != NULL)) {
335
522
                const char *command = menu_command(cmd);
336
523
                const char *argv[4];
337
 
 
338
 
                report(RPT_NOTICE, "Executing: %s", command);
339
 
 
 
524
                pid_t pid;
 
525
                ProcInfo *p;
 
526
                char *envp[cmd->numChildren+1];
 
527
                MenuEntry *arg;
 
528
                int i;
 
529
 
 
530
                /* set argument vector */
340
531
                argv[0] = default_shell;
341
532
                argv[1] = "-c";
342
533
                argv[2] = command;
343
534
                argv[3] = NULL;
344
535
 
345
 
                switch (fork()) {
 
536
                /* set environment vector: allocate & fill contents */
 
537
                for (arg = cmd->children, i = 0; arg != NULL; arg = arg->next, i++) {
 
538
                        char buf[1025];
 
539
 
 
540
                        switch (arg->type) {
 
541
                                case MT_ARG_SLIDER:
 
542
                                        snprintf(buf, sizeof(buf)-1, "%s=%d",
 
543
                                                 arg->name, arg->data.slider.value);
 
544
                                        break;
 
545
                                case MT_ARG_RING:
 
546
                                        snprintf(buf, sizeof(buf)-1, "%s=%s", arg->name,
 
547
                                                 arg->data.ring.strings[arg->data.ring.value]);
 
548
                                        break;
 
549
                                case MT_ARG_NUMERIC:
 
550
                                        snprintf(buf, sizeof(buf)-1, "%s=%d",
 
551
                                                 arg->name, arg->data.numeric.value);
 
552
                                        break;
 
553
                                case MT_ARG_ALPHA:
 
554
                                        snprintf(buf, sizeof(buf)-1, "%s=%s",
 
555
                                                 arg->name, arg->data.alpha.value);
 
556
                                        break;
 
557
                                case MT_ARG_IP:
 
558
                                        snprintf(buf, sizeof(buf)-1, "%s=%s",
 
559
                                                 arg->name, arg->data.ip.value);
 
560
                                        break;
 
561
                                case MT_ARG_CHECKBOX:
 
562
                                        if (arg->data.checkbox.map[arg->data.checkbox.value] != NULL)
 
563
                                            strncpy(buf, arg->data.checkbox.map[arg->data.checkbox.value],
 
564
                                                    sizeof(buf)-1);
 
565
                                        else
 
566
                                                snprintf(buf, sizeof(buf)-1, "%s=%d",
 
567
                                                         arg->name, arg->data.checkbox.value);
 
568
                                        break;
 
569
                                default:
 
570
                                        /* error ? */
 
571
                                        break;
 
572
                        }               
 
573
                        buf[sizeof(buf)-1] ='\0';
 
574
                        envp[i] = strdup(buf);
 
575
 
 
576
                        debug(RPT_DEBUG, "Environment: %s", envp[i]);
 
577
                }
 
578
                envp[cmd->numChildren] = NULL;
 
579
 
 
580
                debug(RPT_DEBUG, "Executing '%s' via Shell %s", command, default_shell);
 
581
 
 
582
                switch (pid = fork()) {
346
583
                  case 0:
347
 
                        /* We're the child. Execute the command. */
348
 
                        execv(argv[0], (char **) argv);
349
 
                        exit(0);
 
584
                        /* We're the child: execute the command */
 
585
                        execve(argv[0], (char **) argv, envp);
 
586
                        exit(EXIT_SUCCESS);
350
587
                        break;
 
588
                  default:
 
589
                        /* We're the parent: setup the ProcInfo structure */
 
590
                        p = calloc(1, sizeof(ProcInfo));
 
591
                        if (p != NULL) {
 
592
                                p->cmd = cmd;
 
593
                                p->pid = pid;
 
594
                                p->starttime = time(NULL);
 
595
                                p->feedback = cmd->data.exec.feedback;
 
596
                                /* prepend it to existing queue atomically */
 
597
                                p->next = proc_queue;
 
598
                                proc_queue = p;
 
599
                        }
 
600
                        break;
351
601
                  case -1:
352
602
                        report(RPT_ERR, "Could not fork");
353
603
                        return -1;
354
 
                  default:
355
 
                        /* We're the parent */
356
 
                        break;
357
604
                }
 
605
 
 
606
                /* free envp's contents */
 
607
                for (i = 0; envp[i] != NULL; i++)
 
608
                        free(envp[i]);
 
609
 
358
610
                return 0;
359
611
        }
360
612
        return -1;
361
613
}
362
614
 
363
615
 
 
616
static int show_procinfo_msg(ProcInfo *p)
 
617
{
 
618
        if ((p != NULL) && (lcd_wid > 0) && (lcd_hgt > 0)) {
 
619
                if (p->endtime > 0) {
 
620
                        /* nothing to do => the quick way out (successful) */
 
621
                        if ((p->shown) || (!p->feedback))
 
622
                                return 1;
 
623
 
 
624
                        sock_printf(sock, "screen_add [%u]\n", p->pid);
 
625
                        sock_printf(sock, "screen_set [%u] -name {lcdexec [%u]}"
 
626
                                          " -priority alert -timeout %d"
 
627
                                          " -heartbeat off\n",
 
628
                                        p->pid, p->pid, 6*8);
 
629
 
 
630
                        if (lcd_hgt > 2) {
 
631
                                sock_printf(sock, "widget_add [%u] t title\n", p->pid);
 
632
                                sock_printf(sock, "widget_set [%u] t {%s}\n", p->pid, p->cmd->displayname);
 
633
                                sock_printf(sock, "widget_add [%u] s1 string\n", p->pid);
 
634
                                sock_printf(sock, "widget_add [%u] s2 string\n", p->pid);
 
635
                                sock_printf(sock, "widget_add [%u] s3 string\n", p->pid);
 
636
 
 
637
                                sock_printf(sock, "widget_set [%u] s1 1 2 {[%u] finished%s}\n",
 
638
                                                p->pid, p->pid, (WIFSIGNALED(p->status) ? "," : ""));
 
639
 
 
640
                                if (WIFEXITED(p->status)) {
 
641
                                        if (WEXITSTATUS(p->status) == EXIT_SUCCESS) {
 
642
                                                sock_printf(sock, "widget_set [%u] s2 1 3 {successfully.}\n",
 
643
                                                                p->pid);
 
644
                                        }
 
645
                                        else {
 
646
                                                sock_printf(sock, "widget_set [%u] s2 1 3 {with code 0x%02X.}\n",
 
647
                                                                p->pid, WEXITSTATUS(p->status));
 
648
                                        }                       
 
649
                                }
 
650
                                else if (WIFSIGNALED(p->status)) {
 
651
                                        sock_printf(sock, "widget_set [%u] s2 1 3 {killed by SIG %d.}\n",
 
652
                                                p->pid, WTERMSIG(p->status));
 
653
                                }
 
654
 
 
655
                                if (lcd_hgt > 3)
 
656
                                        sock_printf(sock, "widget_set [%u] s3 1 4 {Exec time: %lds}\n",
 
657
                                                        p->pid, p->endtime - p->starttime);
 
658
                        }
 
659
                        else {
 
660
                                sock_printf(sock, "widget_add [%u] s1 string\n", p->pid);
 
661
                                sock_printf(sock, "widget_add [%u] s2 string\n", p->pid);
 
662
                                sock_printf(sock, "widget_set [%u] s1 1 1 {%s}\n",
 
663
                                                p->pid, p->cmd->displayname);
 
664
                                if (WIFEXITED(p->status)) {
 
665
                                        if (WEXITSTATUS(p->status) == EXIT_SUCCESS) {
 
666
                                                sock_printf(sock, "widget_set [%u] s2 1 2 {succeeded}\n",
 
667
                                                                p->pid, p->status);
 
668
                                        }
 
669
                                        else {
 
670
                                                sock_printf(sock, "widget_set [%u] s2 1 2 {finished (0x%02X)}\n",
 
671
                                                                p->pid, p->status);
 
672
                                        }
 
673
                                }
 
674
                                else if (WIFSIGNALED(p->status)) {
 
675
                                        sock_printf(sock, "widget_set [%u] s2 1 2 {killed by SIG %d}\n",
 
676
                                                        p->pid, WTERMSIG(p->status));
 
677
                                
 
678
                                }
 
679
                        }
 
680
                        return 1;
 
681
                }
 
682
        }
 
683
        return 0;
 
684
}
 
685
 
 
686
 
364
687
static int main_loop(void)
365
688
{
366
689
        int num_bytes;
367
690
        char buf[100];
368
 
        int w = 0;
 
691
        int keepalive_delay = 0;
 
692
        int status_delay = 0;
369
693
 
370
694
        /* Continuously check if we get a menu event... */
371
 
 
372
 
        while ((num_bytes = sock_recv_string(sock, buf, sizeof(buf)-1)) >= 0) {
 
695
        while (!Quit && ((num_bytes = sock_recv_string(sock, buf, sizeof(buf)-1)) >= 0)) {
373
696
                if (num_bytes == 0) {
 
697
                        ProcInfo *p;
 
698
 
 
699
                        /* wait for 1/10th of a second */
374
700
                        usleep(100000);
375
701
 
376
 
                        /* Send an empty line every 3 seconds to make sure the server still exists */
377
 
                        if (w++ >= 30) {
378
 
                                w = 0;
 
702
                        /* send an empty line every 3 seconds to make sure the server still exists */
 
703
                        if (keepalive_delay++ >= 30) {
 
704
                                keepalive_delay = 0;
379
705
                                if (sock_send_string(sock, "\n") < 0) {
380
706
                                        break; /* Out of while loop */
381
707
                                }
382
708
                        }
 
709
 
 
710
                        /* check for a screen to show and procinfo deletion every second */
 
711
                        if (status_delay++ >= 10) {
 
712
                                status_delay = 0;
 
713
 
 
714
                                /* delete the ProcInfo from the queue */
 
715
                                for (p = proc_queue; p != NULL; p = p->next) {
 
716
                                        ProcInfo *pn = p->next;
 
717
 
 
718
                                        if ((pn != NULL) && (pn->shown)) {
 
719
                                                p->next = pn->next;
 
720
                                                free(pn);
 
721
                                        }
 
722
                                }
 
723
                                /* deleting queue head is special */
 
724
                                if ((proc_queue != NULL) && (proc_queue->shown)) {
 
725
                                        p = proc_queue;
 
726
                                        proc_queue = proc_queue->next;
 
727
                                        free(p);
 
728
                                }
 
729
 
 
730
                                /* look for a process to display, display it & mark it as shown */
 
731
                                for (p = proc_queue; p != NULL; p = p->next) {
 
732
                                        p->shown |= show_procinfo_msg(p);
 
733
                                }
 
734
                        }       
383
735
                }
384
736
                else {
385
737
                        process_response(buf);
386
738
                }
387
739
        }
388
740
 
389
 
        report(RPT_ERR, "Server disconnected (or connection error)");
 
741
        if (!Quit)
 
742
                report(RPT_ERR, "Server disconnected (or connection error)");
390
743
        return 0;
391
744
}
 
745
 
 
746
/* EOF */