10 #include <sys/ioctl.h>
12 #include <linux/ppdev.h>
13 #include <linux/parport.h>
15 static const struct numvalinfo {
19 #define A(x) { #x , PP##x },
43 #define FIND(v, a, d) do{ \
44 for ((v)= a; (v)->name && strcasecmp(arg,(v)->name); (v)++); \
45 if (!(v)->name) badusage("unknown " d); \
48 static const struct numvalinfo modeinfos[] = {
49 #define A(x) { #x , IEEE1284_MODE_##x },
63 struct ppdev_frob_struct fs;
66 static const struct typeinfo {
68 void (*parse)(const char *const **argv);
72 static const void badusage(const char *what) {
73 const struct typeinfo *ti;
74 const struct numvalinfo *ioi;
77 fprintf(stderr,"bad usage: %s\n"
78 "usage: parport-ctl <&parport ioctl"
79 " [output-type [input-type [input-args ...]]]\n"
81 for (ioi= ioctlinfos; ioi->name; ioi++) {
83 for (p= ioi->name; *p; p++)
84 fputc(tolower((unsigned char)*p),stderr);
86 fprintf(stderr,"\ntypes:");
87 for (ti= typeinfos; ti->name; ti++)
88 fprintf(stderr," %s",ti->name);
93 static const char *pa_1arg(const char *const **argv) {
94 const char *arg= *(*argv)++;
95 if (!arg) badusage("input type needs a value");
99 static long pa_int(const char *const **argv) {
100 const char *arg= pa_1arg(argv);
104 l= strtol(arg,&ep,0);
105 if (ep==arg || *ep) badusage("syntactically incorrect numeric input value");
108 static unsigned char pa_uc(const char *const **argv) {
109 long l= pa_int(argv);
110 if (l<-128 || l>255) badusage("input unsigned char out of range");
111 return (unsigned long)l;
114 static void parse_none(const char *const **argv) { }
115 static void parse_int(const char *const **argv) {
116 long l= pa_int(argv);
117 if (l<INT_MIN || l>INT_MAX) badusage("input int out of range");
120 static void parse_uc(const char *const **argv) {
121 parm.uc= pa_uc(argv);
123 static void parse_ppdfs(const char *const **argv) {
124 parm.fs.mask= pa_uc(argv);
125 parm.fs.val= pa_uc(argv);
127 static void parse_mode(const char *const **argv) {
128 const char *arg= pa_1arg(argv);
129 const struct numvalinfo *mi;
130 FIND(mi, modeinfos, "mode name");
134 static void print_none(void) { }
135 static void print_set(void) { }
136 static void print_int(void) { printf("%d\n",parm.i); }
137 static void print_uc(void) { printf("0x%02x\n",parm.uc); }
138 static void print_hex(void) {
139 const unsigned char *p;
140 for (p= (void*)&parm;
141 p < (const unsigned char*)(&parm + 1);
146 static void print_mode(void) {
147 const struct numvalinfo *mi;
148 for (mi= modeinfos; mi->name && mi->num != parm.i; mi++);
149 if (mi->name) printf("%s\n",mi->name);
150 else printf("unknown mode 0x%x\n",parm.i);
152 static void print_dump(void) {
153 const struct typeinfo *ti;
154 for (ti= typeinfos; ti->name; ti++) {
155 if (!ti->print || ti->print==print_dump || ti->print==print_none) continue;
156 printf("%s\t", ti->name);
161 static const struct typeinfo typeinfos[] = {
162 #define T(x) { #x, parse_##x, print_##x },
163 #define TI(x) { #x, parse_##x, 0 },
164 #define TO(x) { #x, 0, print_##x },
176 #define FINDT(v, d, n) do { \
177 FIND((v), typeinfos, "type for " d); \
178 if (!(v)->n) badusage("unsupported type for " d); \
181 int main(int argc, const char *const *argv) {
182 const struct numvalinfo *ioi;
183 const struct typeinfo *iti, *oti;
187 if (!*argv++) badusage("need argv[0]");
188 if (!(arg= *argv++)) badusage("need ioctl name");
189 if (arg[0] == '-') badusage("no options supported");
190 FIND(ioi, ioctlinfos, "ioctl name");
194 FINDT(oti, "type for output from ioctl", print);
198 memset(&parm,0,sizeof(parm));
201 FINDT(iti, "input to ioctl", parse);
204 if (*argv) badusage("too many args");
206 r= ioctl(0, ioi->num, &parm);
207 if (r<0) { perror("parport-ctl: ioctl failed"); exit(-1); }
208 if (r>0) { fprintf(stderr,"parport-ctl: ioctl gave %d!\n",r); }
212 if (ferror(stdout)) { perror("parport-ctl: write stdout"); exit(-1); }
215 return r>125 ? 125 : r;