/* * Copyright (c) 2002, Kalle Carlbark * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the * do *censored* entation and/or other materials provided with the * distribution. * 3. You may not under any circumstances change this license to GPL or dual * license code released under to rootbsd license as gpl. * 4. Neither the name of the RootBSD nor the names of its contributors may be * used to endorse or promote products derived from this software without * specific prior written permission. * 5. Vendors for any derivated commercial software based on code licensed by * the rootbsd license must provide the original programmers with a symbolic * amount of money to show their appreciation to the original programmers * and/or contributors work. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * * This program fork()'s itself into the background and checks for * new mail by using stat() to check when the mailfile is being changed. * When new mail arrives this program calls ioctl() with the * KDSETLED request which'll be switching the capslock led on and off * making it blink. * For FreeBSD 4.x and FreeBSD -CURRENT, probably 3.x as well. * * Author: kc@RootBSD.net * * Greets goes to skypher. * * $Id: ledblink.c,v 1.5 2002/10/03 20:49:20 kc Exp $ * */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #define DURATION 250000 #define OFF 0 #define ON 1 #define CONSOLE 0 #define X 1 static void usage __P((void)); static int daemon_init __P((void)); static int blink __P((int, int)); static int checkmail __P((char *)); static int checkttys __P((int)); static void getsig __P((int)); extern char *__progname; struct stat statbuf; char *ttys[] = { "/dev/ttyv0", "/dev/ttyv1", "/dev/ttyv2", "/dev/ttyv3", "/dev/ttyv4", "/dev/ttyv5", "/dev/ttyv6", "/dev/ttyv7", NULL, }; char *xtty = "/dev/ttyv8"; int fd[9]; int main(argc, argv) int argc; char *argv[]; { int ch, file, gotmail = 0, ttys, state = NULL; char *mailfile; if ((mailfile = getenv("MAIL")) == NULL) bzero(mailfile, sizeof(mailfile)); while ((ch = getopt(argc, argv, "cf:ht:x")) != -1) switch (ch) { case 'c': state = CONSOLE; break; case 'f': mailfile = optarg; if ((file = open(mailfile, O_RDONLY)) == -1) { fprintf(stderr, "%s: %s: %s\n", __progname, mailfile, strerror(errno)); exit(1); } break; case 'h': usage(); break; case 't': xtty = optarg; break; case 'x': setuid(getuid()); if (getuid() != 0) { fprintf(stderr, "The -x flag need to be run as root\n"); exit(1); } state = X; break; case '?': default: usage(); /* NOTREACHED */ } argc -= optind; argv += optind; if (optind < 2) usage(); signal(SIGINT, getsig); signal(SIGTERM, getsig); if (daemon_init() != NULL) exit(1); if ((ttys = checkttys(state)) == -1) { fprintf(stderr, "%s: No valid tty's\n", __progname); exit(EX_NOINPUT); } cap_enter(); for (;;) { if ((checkmail(mailfile)) > 0) { gotmail = 1; } else gotmail = 0; if (gotmail == 1) { blink(ON, ttys); blink(OFF, ttys); } usleep(50000); } return(0); /* NOTREACHED */ } static int blink(OnOFF, ttys) int OnOFF; int ttys; { int i; if (ttys == NULL) { if (ioctl(fd[0], KDSETLED, OnOFF) == -1) { warnx("%s", strerror(errno)); exit(1); } } else { for(i=0;i\tUse another tty than the default /dev/ttyv8\n"); printf("-x\t\t\tBlink in X (require to be run as root).\n\n"); fprintf(stderr, "Usage: %s [-xc] [-f mailfile] [-t /dev/tty*]\n", __progname); exit(EX_USAGE); } static int checkttys(state) int state; { int working = 0; int i = 0; int c = 1; /* XXX: X may use another tty. */ if (state == X) { close(fd[0]); if ((fd[0] = open(xtty, O_RDONLY)) == -1) { warnx("%s", strerror(errno)); exit(EX_DATAERR); } return(NULL); } while (ttys[i] != NULL) { if ((fd[c] = open(ttys[i], O_RDONLY)) != -1) { working += 1; } i++; c++; } if (working == 0) { fprintf(stderr, "%s: No valid tty's\n", __progname); return(-1); } return(working); } static void getsig(signo) int signo; { exit(1); } /* Own version of daemon() :-) */ static int daemon_init() { pid_t pid; if ((pid = fork()) < 0) { warnx("%s", strerror(errno)); exit(EX_UNAVAILABLE); } else if (pid != 0) exit(EX_OK); setsid(); chdir("/"); umask(0); sysconf(_SC_OPEN_MAX); return(0); }