Fix compiler warnings from OS X Lion: a missing #include and some
[sgt/utils] / beep / beep.c
CommitLineData
932fdefd 1/*
6868f2f7 2 * beep: make a beeping noise, by any means necessary
932fdefd 3 */
4
5#include <stdio.h>
6#include <stdlib.h>
7#include <string.h>
8#include <errno.h>
9#include <ctype.h>
10
11#ifndef NO_X11
12#include <X11/X.h>
13#include <X11/Xlib.h>
14#endif
15
16#include <unistd.h>
17#include <fcntl.h>
18
19const char usagemsg[] =
20 "usage: beep [ -v ] ["
21#ifndef NO_X11
22 " -X |"
23#endif
24 " -T | -S ]\n"
25 "where: "
26#ifndef NO_X11
27 "-X beep using the X display or not at all\n "
28#endif
29 "-T beep using /dev/tty or not at all\n"
30 " -S beep using standard output or not at all\n"
31 " -v log failed and successful beep attempts\n"
32 " also: beep --version report version number\n"
33 " beep --help display this help text\n"
34 " beep --licence display the (MIT) licence text\n"
35 ;
36
37void usage(void) {
38 fputs(usagemsg, stdout);
39}
40
41const char licencemsg[] =
42 "beep is copyright 2006 Simon Tatham.\n"
43 "\n"
44 "Permission is hereby granted, free of charge, to any person\n"
45 "obtaining a copy of this software and associated documentation files\n"
46 "(the \"Software\"), to deal in the Software without restriction,\n"
47 "including without limitation the rights to use, copy, modify, merge,\n"
48 "publish, distribute, sublicense, and/or sell copies of the Software,\n"
49 "and to permit persons to whom the Software is furnished to do so,\n"
50 "subject to the following conditions:\n"
51 "\n"
52 "The above copyright notice and this permission notice shall be\n"
53 "included in all copies or substantial portions of the Software.\n"
54 "\n"
55 "THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\n"
56 "EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n"
57 "MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\n"
58 "NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS\n"
59 "BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN\n"
60 "ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN\n"
61 "CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n"
62 "SOFTWARE.\n"
63 ;
64
65void licence(void) {
66 fputs(licencemsg, stdout);
67}
68
69void version(void) {
70#define SVN_REV "$Revision$"
71 char rev[sizeof(SVN_REV)];
72 char *p, *q;
73
74 strcpy(rev, SVN_REV);
75
76 for (p = rev; *p && *p != ':'; p++);
77 if (*p) {
78 p++;
79 while (*p && isspace((unsigned char)*p)) p++;
80 for (q = p; *q && !isspace((unsigned char)*q) && *q != '$'; q++);
81 if (*q) *q = '\0';
82 printf("beep revision %s", p);
83 } else {
84 printf("beep: unknown version");
85 }
86#ifdef NO_X11
87 printf(", compiled without X11");
88#endif
89 putchar('\n');
90}
91
92int main(int argc, char **argv) {
93#ifndef NO_X11
94 char *display = NULL;
95#endif
96 int verbose = 0;
97 enum { X11 = 1, TTY = 2, STDOUT = 4 } mode = X11 | TTY | STDOUT;
98 char errbuf[4096];
99 int errlen = 0;
100 int done = 0;
101 char *pname = argv[0];
102
103 /* parse the command line arguments */
104 while (--argc) {
105 char *p = *++argv;
106
107#ifndef NO_X11
108 if (!strcmp(p, "-display") || !strcmp(p, "-disp")) {
109 if (!argv[1]) {
110 fprintf(stderr, "%s: option `%s' expects a parameter\n",
111 pname, p);
112 return 1;
113 }
114 display = *++argv, --argc;
115 } else if (!strcmp(p, "-X")) {
116 mode = X11;
117 } else
118#endif
119 if (!strcmp(p, "-T")) {
120 mode = TTY;
121 } else if (!strcmp(p, "-S")) {
122 mode = STDOUT;
123 } else if (!strcmp(p, "-v")) {
124 verbose = 1;
125 } else if (!strcmp(p, "--help")) {
126 usage();
127 return 0;
128 } else if (!strcmp(p, "--version")) {
129 version();
130 return 0;
131 } else if (!strcmp(p, "--licence") || !strcmp(p, "--license")) {
132 licence();
133 return 0;
134 } else if (*p=='-') {
135 fprintf(stderr, "%s: unrecognised option `%s'\n", pname, p);
136 return 1;
137 } else {
138 fprintf(stderr, "%s: parameter `%s' unexpected\n", pname, p);
139 return 1;
140 }
141 }
142
143#ifndef NO_X11
144 if (!done && (mode & X11)) {
145 Display *disp = XOpenDisplay(display);
146 if (!disp) {
147 errlen += sprintf(errbuf+errlen,
148 "%s: unable to open X display\n", pname);
149 } else {
150 XBell(disp, 0);
151 XCloseDisplay(disp);
152 if (verbose) {
153 errlen += sprintf(errbuf+errlen,
154 "%s: successfully beeped via X11\n", pname);
155 }
156 done = 1;
157 }
158 }
159#endif
160
161 if (!done && (mode & TTY)) {
162 int fd = open("/dev/tty", O_WRONLY);
163 if (fd < 0) {
164 errlen += sprintf(errbuf+errlen,
165 "%s: unable to open /dev/tty: %s\n",
166 pname, strerror(errno));
167 } else {
168 if (write(fd, "\007", 1) < 0) {
169 errlen += sprintf(errbuf+errlen, "%s: unable to write to"
170 " /dev/tty: %s\n", pname, strerror(errno));
171 } else {
172 if (verbose) {
173 errlen += sprintf(errbuf+errlen, "%s: successfully beeped"
174 " via /dev/tty\n", pname);
175 }
176 done = 1;
177 }
178 close(fd);
179 }
180 }
181
182 if (!done && (mode & STDOUT)) {
183 if (write(1, "\007", 1) < 0) {
184 errlen += sprintf(errbuf+errlen, "%s: unable to write to standard "
185 "output: %s\n", pname, strerror(errno));
186 } else {
187 if (verbose) {
188 errlen += sprintf(errbuf+errlen, "%s: successfully beeped"
189 " via standard output\n", pname);
190 }
191 done = 1;
192 }
193 }
194
195 if (verbose || !done) {
196 errbuf[errlen] = '\0';
197 fputs(errbuf, stderr);
198 }
199
200 return (done ? EXIT_SUCCESS : EXIT_FAILURE);
201}