1 /* $OpenBSD: opt.c,v 1.3 2016/01/08 10:54:07 ratchov Exp $ */ 2 /* 3 * Copyright (c) 2008-2011 Alexandre Ratchov <alex@caoua.org> 4 * 5 * Permission to use, copy, modify, and distribute this software for any 6 * purpose with or without fee is hereby granted, provided that the above 7 * copyright notice and this permission notice appear in all copies. 8 * 9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 16 */ 17 #include <string.h> 18 19 #include "dev.h" 20 #include "opt.h" 21 #include "utils.h" 22 23 struct opt *opt_list = NULL; 24 25 /* 26 * create a new audio sub-device "configuration" 27 */ 28 struct opt * 29 opt_new(char *name, struct dev *dev, 30 int pmin, int pmax, int rmin, int rmax, 31 int maxweight, int mmc, int dup, unsigned int mode) 32 { 33 struct opt *o; 34 unsigned int len; 35 char c; 36 37 if (opt_byname(name, dev->num)) { 38 log_puts(name); 39 log_puts(": already defined\n"); 40 return NULL; 41 } 42 for (len = 0; name[len] != '\0'; len++) { 43 if (len == OPT_NAMEMAX) { 44 log_puts(name); 45 log_puts(": too long\n"); 46 return NULL; 47 } 48 c = name[len]; 49 if ((c < 'a' || c > 'z') && 50 (c < 'A' || c > 'Z')) { 51 log_puts(name); 52 log_puts(": only alphabetic chars allowed\n"); 53 return NULL; 54 } 55 } 56 o = xmalloc(sizeof(struct opt)); 57 if (mode & MODE_PLAY) { 58 o->pmin = pmin; 59 o->pmax = pmax; 60 } 61 if (mode & MODE_RECMASK) { 62 o->rmin = rmin; 63 o->rmax = rmax; 64 } 65 o->maxweight = maxweight; 66 o->mmc = mmc; 67 o->dup = dup; 68 o->mode = mode; 69 o->dev = dev; 70 memcpy(o->name, name, len + 1); 71 o->next = opt_list; 72 opt_list = o; 73 if (log_level >= 2) { 74 dev_log(o->dev); 75 log_puts("."); 76 log_puts(o->name); 77 log_puts(":"); 78 if (o->mode & MODE_REC) { 79 log_puts(" rec="); 80 log_putu(o->rmin); 81 log_puts(":"); 82 log_putu(o->rmax); 83 } 84 if (o->mode & MODE_PLAY) { 85 log_puts(" play="); 86 log_putu(o->pmin); 87 log_puts(":"); 88 log_putu(o->pmax); 89 log_puts(" vol="); 90 log_putu(o->maxweight); 91 } 92 if (o->mode & MODE_MON) { 93 log_puts(" mon="); 94 log_putu(o->rmin); 95 log_puts(":"); 96 log_putu(o->rmax); 97 } 98 if (o->mode & (MODE_RECMASK | MODE_PLAY)) { 99 if (o->mmc) 100 log_puts(" mmc"); 101 if (o->dup) 102 log_puts(" dup"); 103 } 104 log_puts("\n"); 105 } 106 return o; 107 } 108 109 struct opt * 110 opt_byname(char *name, unsigned int num) 111 { 112 struct opt *o; 113 114 for (o = opt_list; o != NULL; o = o->next) { 115 if (o->dev->num != num) 116 continue; 117 if (strcmp(name, o->name) == 0) 118 return o; 119 } 120 return NULL; 121 } 122 123 void 124 opt_del(struct opt *o) 125 { 126 struct opt **po; 127 128 for (po = &opt_list; *po != o; po = &(*po)->next) { 129 #ifdef DEBUG 130 if (*po == NULL) { 131 log_puts("opt_del: not on list\n"); 132 panic(); 133 } 134 #endif 135 } 136 *po = o->next; 137 xfree(o); 138 } 139