aboutsummaryrefslogtreecommitdiffstats
path: root/utils
diff options
context:
space:
mode:
Diffstat (limited to 'utils')
-rw-r--r--utils/Makefile.in31
-rw-r--r--utils/README9
-rw-r--r--utils/down.844
-rw-r--r--utils/down.c129
-rw-r--r--utils/say.135
-rw-r--r--utils/say.c34
-rw-r--r--utils/vmon.865
-rw-r--r--utils/vmon.c442
8 files changed, 789 insertions, 0 deletions
diff --git a/utils/Makefile.in b/utils/Makefile.in
new file mode 100644
index 0000000..8ff750c
--- /dev/null
+++ b/utils/Makefile.in
@@ -0,0 +1,31 @@
+#
+# Template to build speak utilities.
+# $Id: Makefile.in 1.2 Mon, 24 Mar 1997 12:25:37 -0500 dyfet $
+# Copyright (c) 1997 by Tycho Softworks.
+#
+
+UPROGS = say
+SPROGS = down vmon
+PROGS = $(SPROGS) $(UPROGS)
+
+all: $(PROGS)
+
+install: $(PROGS)
+ install -s -g bin $(UPROGS) $(BINDIR)
+ install -s -g bin $(SPROGS) $(SBINDIR)
+ ln -sf $(SBINDIR)/vmon $(SBINDIR)/vstat
+ ../sdk/bin/instman $(MANDIR) 1 say
+ ../sdk/bin/instman $(MANDIR) 8 down vmon
+
+clean:
+ rm $(PROGS)
+
+say: say.c
+ $(CC) $(CFLAGS) $(OPTIMIZE) -I../sdk -L../sdk/lib -o $@ say.c $(LIBS)
+
+down: down.c
+ $(CC) $(CFLAGS) $(OPTIMIZE) -I../sdk -L../sdk/lib -o $@ down.c $(LIBS)
+
+vmon: vmon.c
+ $(CC) $(CFLAGS) $(OPTIMIZE) -I../sdk -L../sdk/lib -o $@ vmon.c $(LIBS)
+
diff --git a/utils/README b/utils/README
new file mode 100644
index 0000000..66d3435
--- /dev/null
+++ b/utils/README
@@ -0,0 +1,9 @@
+This section includes portable 'speak' service based utilities. These
+utilities are being ported from the original WorldVU SPO speak services. So
+far, only "say", "down", and "vmon" have been ported. Additional
+utilities to be added will include a new non-WorldVU related user session
+announcement daemon, perhaps as part of vmon. The original user session
+monitoring utility was closely tied into the WorldVU user cluster
+monitoring system.
+
+
diff --git a/utils/down.8 b/utils/down.8
new file mode 100644
index 0000000..fe0b81d
--- /dev/null
+++ b/utils/down.8
@@ -0,0 +1,44 @@
+.TH "down" "8" "January 1997" "Speak 0.2" "Text-to-Speech"
+.PP
+.SH NAME
+.PP
+\fBdown\fP - warn and then shutdown system.
+.PP
+.SH SYNOPSIS
+.PP
+\fBdown\fP [\fIseconds\fP]
+.PP
+.SH DESCRIPTION
+.PP
+The Text-to-speech package introduces a standard TCP/IP port service for
+attaching text-to-speech resources to your network. These resources can
+be used to monitor system status, provide verbal alarms, etc. This network
+service may be accessed by telnetting to a machine running a "speak" server,
+or by using the various application utilities, such as \fBdown\fP.
+.PP
+
+The \fBdown\fP program will provide a warning with a countdown that may
+be aborted. When the countdown reaches 0, your system will begin a normal
+shutdown and reboot. The warning and countdown is shown on screen and
+spoken over the text-to-speech interface. The \fBdown\fP program uses the
+[\fIdown\fP] information in \fBspeak.conf\fP for default values. Only an
+alternate countdown (in seconds) may be specified via a command line
+argument.
+
+.PP
+The [\fIdown\fP] section specifies a default timer to use, the hostname
+where the speech server is running, and the program to execute to bring
+the system down. If you are using \fBdown\fP on a machine that does not
+have it's own text-to-speech server, then you will need to create a local
+\fB/etc/speak.conf\fP file on that machine with at minimum a [\fIdown\fP]
+section with an entry for the text-to-speech host server to use.
+
+.PP
+.SH SEE ALSO
+.PP
+.BR speak.conf (7)
+.PP
+.SH AUTHOR
+.PP
+David Sugar (dyfet@tycho.com)
+.PP
diff --git a/utils/down.c b/utils/down.c
new file mode 100644
index 0000000..66d9d19
--- /dev/null
+++ b/utils/down.c
@@ -0,0 +1,129 @@
+/*
+ * A verbal system shutdown utility.
+ * $Id: down.c 1.2 Mon, 24 Mar 1997 12:25:37 -0500 dyfet $
+ * Copyright (c) 1997 by Tycho Softworks.
+ * For conditions of distribution and reuse see product license.
+ *
+ * Abstract:
+ * A verbal system shutdown utility. You may need to adjust the name
+ * of the shutdown program used. This gives some warning and then
+ * initiates the shutdown processing, unless cancelled in time.
+ */
+
+#include <std/signal.h>
+#include <proc/process.h>
+#include <other/string.h>
+#include <std/files.h>
+#include <other/config.h>
+#include <net/stream.h>
+
+static char host[128] = "localhost";
+static char halt[60] = "/sbin/halt";
+static char abort_msg[] = "System shutdown overriden. Resuming normal operation.\n";
+static char down_msg[] = "%s system shutdown sequence initiated. You have %d seconds to override.\n";
+static int timer = 10;
+static STREAM fp = NULL;
+
+/*
+ * If the user aborts the shutdown, then we send the cancellation message
+ * and gracefully exit the scene.
+ */
+
+static void abort_sig()
+{
+ if(fp)
+ {
+ puttcp(abort_msg, fp);
+ closetcp(fp);
+ }
+ fputs("\n", stdout);
+ exit(-1);
+}
+
+void main(int argc, char **argv)
+{
+ char *p;
+ char *reboot = halt;
+ int port = getservice("speak");
+ CONFIG *cfg = sys_config("speak");
+ char hostname[128];
+
+ if(argc < 1 || argc > 2)
+ fatal(EX_USAGE, "use: down [timer]\n");
+
+ if(!port)
+ fatal(EX_UNAVAILABLE, "down: speak: service unlisted in /etc/services\n");
+
+ if(!cfg)
+ fatal(EX_CONFIG, "down: speak.conf: config missing\n");
+
+ seek_config(cfg, "down");
+ while(read_config(cfg))
+ {
+ if(NULL != (p = get_config(cfg, "timer")))
+ {
+ timer = atoi(p);
+ continue;
+ }
+
+ if(NULL != (p = get_config(cfg, "halt")))
+ {
+ strcpy(halt, p);
+ continue;
+ }
+
+ if(NULL != (p = get_config(cfg, "host")))
+ {
+ strcpy(host, p);
+ continue;
+ }
+
+ if(NULL != (p = get_config(cfg, "server")))
+ {
+ strcpy(host, p);
+ continue;
+ }
+ }
+ close_config(cfg);
+ if(argc > 1)
+ timer = atoi(argv[1]);
+
+ fp = opentcp(host, port);
+ if(!fp)
+ fatal(EX_UNAVAILABLE, "down: %s: speak service unreachable\n", host);
+
+ printf("System shutdown initiated...use <break> to override; ");
+ fflush(stdout);
+ signal(SIGINT, abort_sig);
+ gettcp(hostname, 127, fp);
+ gethostname(hostname, 80);
+ fprintf(fp, down_msg, hostname, timer);
+ fflush(fp);
+ sleep(strlen(down_msg) / 9 + 1);
+
+ /* count down timer until 0 */
+
+ while(timer)
+ {
+ printf("%d ", timer);
+ fflush(stdout);
+ fprintf(fp, "%d\n", timer);
+ fflush(fp);
+ sleep(1);
+ --timer;
+ }
+
+ /* too late now!! */
+
+ signal(SIGINT, SIG_IGN);
+ printf("\n");
+ closetcp(fp);
+
+ /* detach return to user and execute reboot program */
+
+ pdetach(D_KEEPALL);
+ argv[0] = reboot;
+ argv[1] = NULL;
+ execvp(reboot, argv);
+}
+
diff --git a/utils/say.1 b/utils/say.1
new file mode 100644
index 0000000..1807b76
--- /dev/null
+++ b/utils/say.1
@@ -0,0 +1,35 @@
+.TH "say" "1" "January 1997" "Speak 0.2" "Text-to-Speech"
+.PP
+.SH NAME
+.PP
+\fBsay\fP - send output string to text-to-speech service.
+.PP
+.SH SYNOPSIS
+.PP
+\fBspeak\fP \fIhostname\fP "\fImessage\fP"
+.PP
+.SH DESCRIPTION
+.PP
+The Text-to-speech package introduces a standard TCP/IP port service for
+attaching text-to-speech resources to your network. These resources can
+be used to monitor system status, provide verbal alarms, etc. This network
+service may be accessed by telnetting to a machine running a "speak" server,
+or by using the various application utilities, such as \fBsay\fP.
+.PP
+
+The \fBsay\fP program will send a specified string of text to a specified
+network speech server. The intent is to use say to produce verbal output
+much like the way "echo" may be used to create screen output. \fBsay\fP
+will form a momentary connection with the speech server (such as
+\fBspo256\fP), send the message, and then disconnect. The TCP
+service port used for the connection is specified in \fI/etc/services\fP.
+
+.PP
+.SH SEE ALSO
+.PP
+.BR speak (1)
+.PP
+.SH AUTHOR
+.PP
+David Sugar (dyfet@tycho.com)
+.PP
diff --git a/utils/say.c b/utils/say.c
new file mode 100644
index 0000000..b774eaf
--- /dev/null
+++ b/utils/say.c
@@ -0,0 +1,34 @@
+/*
+ * Send text to speech server. May be used in script files.
+ * $Id: say.c 1.2 Mon, 24 Mar 1997 12:25:37 -0500 dyfet $
+ * Copyright (c) 1997 by Tycho Softworks.
+ * For conditions on distribution and reuse see product license.
+ */
+
+#include <std/string.h>
+#include <std/process.h>
+#include <net/stream.h>
+
+void main(int argc, char **argv)
+{
+ STREAM fp;
+ int port = getservice("speak");
+ char buf[128];
+
+ if(argc != 3)
+ fatal(EX_USAGE, "use: say host \"message\"\n");
+
+ if(!port)
+ fatal(EX_UNAVAILABLE, "say: speak: service not in /etc/services\n");
+
+ fp = opentcp(argv[1], port);
+ if(!fp)
+ fatal(EX_UNAVAILABLE, "say: %s: speak service unavailable\n", argv[1]);
+
+ gettcp(buf, 127, fp);
+ puttcp(argv[2], fp);
+ puttcp("\n", fp);
+ closetcp(fp);
+}
+
+
diff --git a/utils/vmon.8 b/utils/vmon.8
new file mode 100644
index 0000000..84a1308
--- /dev/null
+++ b/utils/vmon.8
@@ -0,0 +1,65 @@
+.TH "vmon" "8" "January 1997" "Speak 0.2" "Text-to-Speech"
+.PP
+.SH NAME
+.PP
+\fBvmon\fP - monitor system status (town crier).
+.PP
+.SH SYNOPSIS
+.PP
+\fBvmon\fP \fIfilesystems\fP
+.br
+\fBvstat\fP \fIfilesystems\fP
+.PP
+.SH DESCRIPTION
+.PP
+The Text-to-speech package introduces a standard TCP/IP port service for
+attaching text-to-speech resources to your network. These resources can
+be used to monitor system status, provide verbal alarms, etc. This network
+service may be accessed by telnetting to a machine running a "speak" server,
+or by using the various application utilities, such as \fBvmon\fP.
+.PP
+
+The \fBvmon\fP program will monitor the specified list of file systems.
+If any of these file systems exceed a maximum "quota" (such as over 90%
+capacity in blocks or i-node use), then the monitor will send verbal
+alerts every 5 minutes. This quota, and other parameters for vmon, may
+be found in the [\fIvmon\fP] section of \fBspeak.conf\fP.
+.PP
+
+The \fBvmon\fP program will also announce current system status once
+every hour. This system status includes the total used capacity of
+all file systems being monitored, how long the system has been up, and
+how many users are currently logged in (excluding root). This hourly
+announcement can be used to determine a given system is still alive.
+.PP
+
+The \fBvmon\fP program will now also monitor specified user mailboxes
+for new mail and announce when new mail arrives. The users to be
+monitored are specified in the [\fIvmon\fP] section of \fBspeak.conf\fP.
+Simply list mailbox= entries for each mailbox you wish to monitor. See
+the example speak.conf included with the distribution.
+.PP
+
+The \fBvmon\fP program can also be ran as \fBvstat\fP. When used as
+\fBvstat\fP, the program performs an immediate system check, announces,
+and then terminates. You can either use \fBvstat\fP from a crontab or
+start \fBvmon\fP from \fBspeak.init\fP. You may also start \fBvmon\fP
+from a \fBrc.local\fP file. Please check the \fBspeak.init\fP file
+to add any file systems you wish to monitor. By default, the root
+filesystem is enabled in \fBspeak.init\fP.
+.PP
+
+A mute option may also be specified in the [\fIvmon\fP] section of
+\fBspeak.conf\fP. This option mutes voice output during certain times of
+the day. This is normally specified by 24 hour clock in hours, hence 18-7
+means to mute output anytime after 18' hours (6pm) and anytime before 7'
+hours (7am).
+.PP
+.SH SEE ALSO
+.PP
+.BR speak.conf (7)
+.PP
+.SH AUTHOR
+.PP
+David Sugar (dyfet@tycho.com)
+.PP
diff --git a/utils/vmon.c b/utils/vmon.c
new file mode 100644
index 0000000..e1015b4
--- /dev/null
+++ b/utils/vmon.c
@@ -0,0 +1,442 @@
+/* Verbal monitor system status.
+ * $Id: vmon.c 1.2 Mon, 24 Mar 1997 12:25:37 -0500 dyfet $
+ * Copyright (c) 1997 by Tycho Softworks.
+ * For conditions on distribution and reuse see product license.
+ *
+ * Abstract:
+ * Monitor system status in background. This service is normally
+ * started with the speech server. It may also be ran as 'vstat'
+ * to perform immediate notification.
+ */
+
+#include <std/time.h>
+#include <other/string.h>
+#include <proc/process.h>
+#include <other/config.h>
+#include <net/stream.h>
+#include <std/utmp.h>
+
+/* For systems that use statfs! */
+
+#ifdef __linux__
+#include <sys/vfs.h>
+#define __statfs__
+#endif
+
+typedef struct _MAILBOX
+{
+ struct _MAILBOX *next;
+ time_t update;
+ ulong size;
+ char name[0];
+} MAILBOX;
+
+static int freq = 3600;
+static int timer = 3600;
+static int interval = 300;
+static int iter;
+static int orig_timer;
+static int alert = 90; /* warn on 90% full */
+static char alertmsg[] = "emergency alert emergency alert \r\n";
+static char **fs;
+static char host[128] = "localhost";
+static int mute[2] = {24, 0};
+
+static char *vmailbox(MAILBOX *mbox)
+{
+ struct stat ino;
+ static char buf[80];
+
+ if(stat(mbox->name, &ino))
+ return NULL;
+
+ if(!ino.st_size)
+ {
+ mbox->size = 0;
+ return NULL;
+ }
+
+ if(ino.st_size == mbox->size)
+ return NULL;
+
+ if(mbox->size == -1)
+ {
+ mbox->size = ino.st_size;
+ return NULL;
+ }
+
+ mbox->size = ino.st_size;
+ sprintf(buf, "User %s has new mail\n", mbox->name);
+ return buf;
+}
+
+static void vmbox(MAILBOX *box, int port)
+{
+ STREAM fp = NULL;
+ char *p;
+ time_t now;
+ struct tm *dt;
+ char buf[128];
+
+ time(&now);
+ dt = localtime(&now);
+ if(dt->tm_hour > mute[0] || dt->tm_hour < mute[1])
+ return;
+
+ while(box)
+ {
+ p = vmailbox(box);
+ if(!p)
+ {
+ box = box->next;
+ continue;
+ }
+ if(!fp)
+ {
+ fp = opentcp(host, port);
+ if(!fp)
+ return;
+
+ gettcp(buf, sizeof(buf) - 1, fp);
+ }
+ puttcp(p, fp);
+ box = box->next;
+ }
+ if(fp)
+ closetcp(fp);
+}
+
+static int vstat(int port)
+{
+ int i = 0;
+ char *f;
+ long btotal = 0;
+ long bfree = 0;
+ bool failed = FALSE;
+ STREAM fp = NULL;
+#ifdef __statfs__
+ struct statfs fnode;
+#endif
+ int blocks, inodes;
+ char buf[128];
+ int newtimer = orig_timer;
+ time_t now;
+ static prior = -1;
+ struct tm *dt;
+ int apm, hour;
+ char *apmstr[] = {" A M ", " P M "};
+ int fd;
+ struct utmp *utmp, uptime;
+ int users = 0;
+ int utcnt = 0;
+
+#ifdef __statfs__
+ while(fs[i])
+ {
+ if(!statfs(fs[i], &fnode))
+ {
+ btotal += fnode.f_blocks;
+ bfree += fnode.f_bfree;
+ blocks = 100 - (int)(fnode.f_ffree / (fnode.f_files / 100l));
+ inodes = 100 - (int)(fnode.f_bfree / (fnode.f_blocks / 100l));
+ if((blocks < alert) && (inodes < alert))
+ {
+ ++i;
+ continue;
+ }
+ }
+ else
+ {
+ inodes = 0;
+ blocks = 0;
+ failed = TRUE;
+ }
+ if(!fp)
+ {
+ fp = opentcp(host, port);
+ if(!fp)
+ {
+ newtimer = 300;
+ break;
+ }
+ gettcp(buf, 128, fp);
+ puttcp(alertmsg, fp);
+ }
+
+ if(blocks > alert)
+ fprintf(fp, "File system %s is %d percent full.\r\n", fs[i], blocks);
+
+ if(inodes > alert)
+ fprintf(fp, "File system %s i-node table is %d percent full.\r\n", fs[i], inodes);
+
+ if(failed)
+ fprintf(fp, "File system %s is dismounted or failed\r\n", fs[i]);
+
+ fflush(fp);
+ newtimer = 60;
+ ++i;
+ }
+#endif
+
+ if(fp)
+ closetcp(fp);
+
+ time(&now);
+ if(prior == (now / freq))
+ return newtimer;
+
+ if(prior == -1)
+ prior = now / freq - 1;
+ else
+ prior = now / freq;
+
+ dt = localtime(&now);
+ hour = dt->tm_hour % 12;
+ if(dt->tm_hour > mute[0] || dt->tm_hour < mute[1])
+ return newtimer;
+
+ if(!hour)
+ hour = 12;
+
+ if(dt->tm_hour > 11)
+ apm = 1;
+ else
+ apm = 0;
+
+ fp = opentcp(host, port);
+ if(!fp)
+ return newtimer;
+
+ gettcp(buf, 128, fp);
+ fprintf(fp, "It is %d:%d %s \r\n", hour, dt->tm_min, apmstr[apm]);
+ fflush(fp);
+
+ fd = open("/proc/uptime", O_RDONLY);
+ hour = -1;
+ if(fd > -1)
+ {
+ read(fd, buf, 128);
+ close(fd);
+ hour = atol(buf) / 3600;
+ }
+
+#if defined(BOOT_TIME) || defined(RUN_LVL)
+ if(hour == -1)
+ {
+ utmp = NULL;
+ memset(&uptime, 0, sizeof(uptime));
+#ifdef BOOT_TIME
+ setutent();
+ uptime.ut_type = BOOT_TIME;
+ utmp = getutid(&uptime);
+#endif
+#ifdef RUN_LVL
+ if(!utmp)
+ {
+ setutent();
+ uptime.ut_type = RUN_LVL;
+ utmp = getutid(&uptime);
+ }
+#endif
+ if(utmp)
+ hour = (now - utmp->ut_time) / 3600l;
+
+ endutent();
+ }
+#endif
+
+ if(hour > -1)
+ {
+ if(hour == 1)
+ fprintf(fp, "The system has been up 1 hour\r\n");
+ else if(hour < 48)
+ fprintf(fp, "The system has been up %d hours\r\n", hour);
+ else
+ fprintf(fp, "The system has been up %d days\r\n", hour / 24);
+ fflush(fp);
+ }
+
+ setutent();
+ while(NULL != (utmp = getutent()))
+ {
+ ++utcnt;
+
+#ifdef USER_PROCESS
+ if(utmp->ut_type != USER_PROCESS)
+ continue;
+#endif
+
+ utmp->ut_user[sizeof(utmp->ut_user)] = 0;
+ if(!strcmp(utmp->ut_user, "root"))
+ continue;
+
+ if(!utmp->ut_user[0])
+ continue;
+
+ if(!utmp->ut_line[0])
+ continue;
+
+#ifdef USER_PROCESS
+ if(kill(utmp->ut_pid, 0))
+ continue;
+#endif
+
+ ++users;
+ }
+ endutent();
+
+ if(utcnt)
+ {
+ if(!users)
+ fprintf(fp, "There are no users online\r\n");
+ else if(users == 1)
+ fprintf(fp, "There is 1 user online\r\n");
+ else
+ fprintf(fp, "There are %d users online\r\n", users);
+ fflush(fp);
+ }
+
+ if(btotal)
+ {
+ fprintf(fp, "The main system drives are at %d percent of capacity\r\n",
+ 100 - (int)(bfree / (btotal / 100)));
+ fflush(fp);
+ }
+
+ closetcp(fp);
+ return newtimer;
+}
+
+void main(int argc, char **argv)
+{
+ int port = getservice("speak");
+ char *maildir = getenv("MAILDIR");
+ MAILBOX *mbox = NULL, *newbox;
+ char *prog = basename(*argv);
+ CONFIG *cfg = sys_config("speak");
+ time_t now;
+ char *p;
+
+ if(argc < 2)
+ fatal(EX_USAGE, "use %s filesystems...\n", prog);
+
+ if(!maildir)
+ maildir = "/var/spool/mail";
+
+ fs = ++argv;
+
+ if(!port)
+ fatal(EX_UNAVAILABLE, "%s: speak: service unavailable\n", prog);
+
+ if(!cfg)
+ fatal(EX_UNAVAILABLE, "%s: speak.conf: missing\n", prog);
+
+ seek_config(cfg, "vmon");
+ while(read_config(cfg))
+ {
+ if(NULL != (p = get_config(cfg, "mailbox")))
+ {
+ p = strtok(p, __SPACES);
+ while(p)
+ {
+ newbox = (MAILBOX *)malloc(sizeof(MAILBOX) + strlen(p) + 1);
+ newbox->next = mbox;
+ time(&newbox->update);
+ newbox->size = -1l;
+ strcpy(newbox->name, p);
+ mbox = newbox;
+ p = strtok(NULL, __SPACES);
+ }
+ continue;
+ }
+
+ if(NULL != (p = get_config(cfg, "interval")))
+ {
+ interval = atoi(p) * 60;
+ continue;
+ }
+
+ if(NULL != (p = get_config(cfg, "frequency")))
+ {
+ timer = 3600 / atoi(p);
+ continue;
+ }
+
+ if(NULL != (p = get_config(cfg, "server")))
+ {
+ strcpy(host, p);
+ continue;
+ }
+
+ if(NULL != (p = get_config(cfg, "host")))
+ {
+ strcpy(host, p);
+ continue;
+ }
+
+ if(NULL != (p = get_config(cfg, "alert")))
+ {
+ alert = atoi(p);
+ continue;
+ }
+
+ if(NULL != (p = get_config(cfg, "timer")))
+ {
+ timer = atoi(p) * 60;
+ continue;
+ }
+
+ if(NULL != (p = get_config(cfg, "mute")))
+ {
+ mute[0] = atoi(p);
+ p = strchr(p, '-');
+ if(p)
+ mute[1] = atoi(strtrim(++p, __SPACES));
+ continue;
+ }
+
+ if(NULL != (p = get_config(cfg, "maildir")))
+ {
+ maildir = strdup(p);
+ continue;
+ }
+
+ }
+ close_config(cfg);
+
+ if(stricmp(prog, "vmon"))
+ {
+ vstat(port);
+ exit(0);
+ }
+
+ pdetach(D_KEEPNONE);
+
+ chdir(maildir);
+ freq = timer;
+ orig_timer = timer;
+ time(&now);
+ for(;;)
+ {
+ timer = vstat(port);
+ iter = interval;
+ for(;;)
+ {
+ vmbox(mbox, port);
+ sleep(iter);
+ time(&now);
+ iter = timer - (now % timer) - 1;
+
+ if(iter > interval)
+ iter = interval;
+
+ if(iter < 2)
+ {
+ sleep(iter + 2);
+ break;
+ }
+ }
+ }
+}
+
+