1 /*        $NetBSD: bellctrl.c,v 1.13 2011/08/25 17:00:55 christos Exp $         */
2 
3 /*
4  * bellctrl - OPM bell controller (for NetBSD/X680x0)
5  * Copyright (c)1995 ussy.
6  */
7 
8 #include <sys/cdefs.h>
9 __RCSID("$NetBSD: bellctrl.c,v 1.13 2011/08/25 17:00:55 christos Exp $");
10 
11 #include <err.h>
12 #include <stdio.h>
13 #include <stdlib.h>
14 #include <unistd.h>
15 #include <ctype.h>
16 #include <string.h>
17 #include <sys/file.h>
18 #include <sys/ioctl.h>
19 #include <machine/opmbellio.h>
20 
21 #define DEFAULT -1
22 
23 #define nextarg(i, argv) \
24           argv[i]; \
25           if (i >= argc) \
26                     break; \
27 
28 static int bell_setting;
29 static struct opm_voice voice;
30 
31 static struct opm_voice bell_voice = DEFAULT_BELL_VOICE;
32 
33 static struct bell_info values = {
34           DEFAULT, DEFAULT, DEFAULT
35 };
36 
37 /* function prototype */
38 static int is_number(const char *, int);
39 static void set_bell_vol(int);
40 static void set_bell_pitch(int);
41 static void set_bell_dur(int);
42 static void set_voice_param(const char *, int);
43 static void set_bell_param(void);
44 static void usage(void) __dead;
45 
46 int
main(int argc,char ** argv)47 main(int argc, char **argv)
48 {
49           const char *arg;
50           int percent;
51           int i;
52 
53           bell_setting = 0;
54 
55           if (argc < 2)
56                     usage();
57 
58           for (i = 1; i < argc; ) {
59                     arg = argv[i++];
60                     if (strcmp(arg, "-b") == 0) {
61                               /* turn off bell */
62                               set_bell_vol(0);
63                     } else if (strcmp(arg, "b") == 0) {
64                               /* set bell to default */
65                               percent = DEFAULT;
66 
67                               if (i >= argc) {
68                                         /* set bell to default */
69                                         set_bell_vol(percent);
70                                         /* set pitch to default */
71                                         set_bell_pitch(percent);
72                                         /* set duration to default */
73                                         set_bell_dur(percent);
74                                         break;
75                               }
76                               arg = nextarg(i, argv);
77                               if (strcmp(arg, "on") == 0) {
78                                         /*
79                                          * let it stay that way
80                                          */
81                                         /* set bell on */
82                                         set_bell_vol(BELL_VOLUME);
83                                         /* set pitch to default */
84                                         set_bell_pitch(BELL_PITCH);
85                                         /* set duration to default */
86                                         set_bell_dur(BELL_DURATION);
87                                         i++;
88                               } else if (strcmp(arg, "off") == 0) {
89                                         /* turn the bell off */
90                                         percent = 0;
91                                         set_bell_vol(percent);
92                                         i++;
93                               } else if (is_number(arg, MAXBVOLUME)) {
94                                         /*
95                                          * If volume is given
96                                          */
97                                         /* set bell appropriately */
98                                         percent = atoi(arg);
99 
100                                         set_bell_vol(percent);
101                                         i++;
102 
103                                         arg = nextarg(i, argv);
104 
105                                         /* if pitch is given */
106                                         if (is_number(arg, MAXBPITCH)) {
107                                                   /* set the bell */
108                                                   set_bell_pitch(atoi(arg));
109                                                   i++;
110 
111                                                   arg = nextarg(i, argv);
112                                                   /* If duration is given       */
113                                                   if (is_number(arg, MAXBTIME)) {
114                                                             /* set the bell */
115                                                             set_bell_dur(atoi(arg));
116                                                             i++;
117                                                   }
118                                         }
119                               } else {
120                                         /* set bell to default */
121                                         set_bell_vol(BELL_VOLUME);
122                               }
123                     } else if (strcmp(arg, "v") == 0) {
124                               /*
125                                * set voice parameter
126                                */
127                               if (i >= argc) {
128                                         arg = "default";
129                               } else {
130                                         arg = nextarg(i, argv);
131                               }
132                               set_voice_param(arg, 1);
133                               i++;
134                     } else if (strcmp(arg, "-v") == 0) {
135                               /*
136                                * set voice parameter
137                                */
138                               if (i >= argc) {
139                                         warnx("Missing -v argument");
140                                         usage();
141                               }
142                               arg = nextarg(i, argv);
143                               set_voice_param(arg, 0);
144                               i++;
145                     } else {
146                               warnx("Unknown option %s", arg);
147                               usage();
148                     }
149           }
150 
151           if (bell_setting)
152                     set_bell_param();
153 
154           exit(0);
155 }
156 
157 static int
is_number(const char * arg,int maximum)158 is_number(const char *arg, int maximum)
159 {
160           const char *p;
161 
162           if (arg[0] == '-' && arg[1] == '1' && arg[2] == '\0')
163                     return 1;
164           for (p = arg; isdigit((unsigned char)*p); p++)
165                     ;
166           if (*p || atoi(arg) > maximum)
167                     return 0;
168 
169           return 1;
170 }
171 
172 static void
set_bell_vol(int percent)173 set_bell_vol(int percent)
174 {
175           values.volume = percent;
176           bell_setting++;
177 }
178 
179 static void
set_bell_pitch(int pitch)180 set_bell_pitch(int pitch)
181 {
182           values.pitch = pitch;
183           bell_setting++;
184 }
185 
186 static void
set_bell_dur(int duration)187 set_bell_dur(int duration)
188 {
189           values.msec = duration;
190           bell_setting++;
191 }
192 
193 static void
set_voice_param(const char * path,int flag)194 set_voice_param(const char *path, int flag)
195 {
196           int fd;
197 
198           if (flag) {
199                     memcpy(&voice, &bell_voice, sizeof(bell_voice));
200           } else {
201                     if ((fd = open(path, 0)) >= 0) {
202                               if (read(fd, &voice, sizeof(voice)) != sizeof(voice))
203                                         err(1, "cannot read voice parameter");
204                               close(fd);
205                     } else {
206                               err(1, "cannot open voice parameter");
207                     }
208           }
209 
210           if ((fd = open("/dev/bell", O_RDWR)) < 0)
211                     err(1, "cannot open /dev/bell");
212           if (ioctl(fd, BELLIOCSVOICE, &voice))
213                     err(1, "ioctl BELLIOCSVOICE failed");
214 
215           close(fd);
216 }
217 
218 static void
set_bell_param(void)219 set_bell_param(void)
220 {
221           int fd;
222           struct bell_info param;
223 
224           if ((fd = open("/dev/bell", O_RDWR)) < 0)
225                     err(1, "cannot open /dev/bell");
226           if (ioctl(fd, BELLIOCGPARAM, &param))
227                     err(1, "ioctl BELLIOCGPARAM failed");
228 
229           if (values.volume == DEFAULT)
230                     values.volume = param.volume;
231           if (values.pitch == DEFAULT)
232                     values.pitch = param.pitch;
233           if (values.msec == DEFAULT)
234                     values.msec = param.msec;
235 
236           if (ioctl(fd, BELLIOCSPARAM, &values))
237                     err(1, "ioctl BELLIOCSPARAM failed");
238 
239           close(fd);
240 }
241 
242 static void
usage(void)243 usage(void)
244 {
245           fprintf(stderr, "Usage: %s option ...\n", getprogname());
246           fprintf(stderr, "   To turn bell off:\n");
247           fprintf(stderr, "\t-b                                       b off"
248                           "                          b 0\n");
249           fprintf(stderr, "   To set bell volume, pitch and duration:\n");
250           fprintf(stderr, "\t b [vol [pitch [dur]]]                     b on\n");
251           fprintf(stderr, "   To restore default voice parameter:\n");
252           fprintf(stderr, "\t v default\n");
253           fprintf(stderr, "   To set voice parameter:\n");
254           fprintf(stderr, "\t-v voicefile\n");
255           exit(0);
256 }
257