chiark / gitweb /
seems to work
authorian <ian>
Sun, 8 Aug 2004 20:22:03 +0000 (20:22 +0000)
committerian <ian>
Sun, 8 Aug 2004 20:22:03 +0000 (20:22 +0000)
parport/.cvsignore [new file with mode: 0644]
parport/Makefile [new file with mode: 0644]
parport/parport-ctl.c [new file with mode: 0644]

diff --git a/parport/.cvsignore b/parport/.cvsignore
new file mode 100644 (file)
index 0000000..af0105d
--- /dev/null
@@ -0,0 +1 @@
+parport-ctl
diff --git a/parport/Makefile b/parport/Makefile
new file mode 100644 (file)
index 0000000..4be6f6a
--- /dev/null
@@ -0,0 +1,5 @@
+CFLAGS=        -Wall -Wwrite-strings -Wpointer-arith \
+       -Wnested-externs -Wmissing-prototypes -Wstrict-prototypes \
+       -O2
+
+targets:       parport-ctl
diff --git a/parport/parport-ctl.c b/parport/parport-ctl.c
new file mode 100644 (file)
index 0000000..e368336
--- /dev/null
@@ -0,0 +1,216 @@
+/**/
+
+#include <unistd.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <limits.h>
+#include <string.h>
+#include <ctype.h>
+
+#include <sys/ioctl.h>
+#include <sys/time.h>
+#include <linux/ppdev.h>
+#include <linux/parport.h>
+
+static const struct numvalinfo {
+  const char *name;
+  int num;
+} ioctlinfos[] = {
+#define A(x) { #x , PP##x },
+  A(CLAIM)
+  A(EXCL)
+  A(RELEASE)
+  A(YIELD)
+  A(NEGOT)
+  A(SETMODE)
+  A(GETMODE)
+  A(GETTIME)
+  A(GETMODES)
+  A(SETFLAGS)
+  A(WCONTROL)
+  A(RCONTROL)
+  A(FCONTROL)
+  A(RSTATUS)
+  A(DATADIR)
+  A(WDATA)
+  A(RDATA)
+  A(CLRIRQ)
+  A(WCTLONIRQ)
+#undef A
+  { 0 }
+};
+
+#define FIND(v, a, d) do{                                              \
+    for ((v)= a; (v)->name && strcasecmp(arg,(v)->name); (v)++);       \
+    if (!(v)->name) badusage("unknown " d);                            \
+  }while(0)
+
+static const struct numvalinfo modeinfos[] = {
+#define A(x) { #x , IEEE1284_MODE_##x },
+  A(COMPAT)
+  A(NIBBLE)
+  A(BYTE)
+  A(EPP)
+  A(ECP)
+#undef A
+  { 0 }
+};
+
+static union parm {
+  int i;
+  struct timeval tv;
+  unsigned char uc;
+  struct ppdev_frob_struct fs;
+} parm;
+
+static const struct typeinfo {
+  const char *name;
+  void (*parse)(const char *const **argv);
+  void (*print)(void);
+} typeinfos[];
+
+static const void badusage(const char *what) {
+  const struct typeinfo *ti;
+  const struct numvalinfo *ioi;
+  const char *p;
+  
+  fprintf(stderr,"bad usage: %s\n"
+         "usage: parport-ctl <&parport ioctl"
+         " [input-type [input-args ...] [output-type]]\n"
+         "ioctls:", what);
+  for (ioi= ioctlinfos; ioi->name; ioi++) {
+    fputc(' ',stderr);
+    for (p= ioi->name; *p; p++)
+      fputc(tolower((unsigned char)*p),stderr);
+  }
+  fprintf(stderr,"\ntypes:");
+  for (ti= typeinfos; ti->name; ti++)
+    fprintf(stderr," %s",ti->name);
+  fputc('\n',stderr);
+  exit(126);
+}
+
+static const char *pa_1arg(const char *const **argv) {
+  const char *arg= *(*argv)++;
+  if (!arg) badusage("input type needs a value");
+  return arg;
+}            
+
+static long pa_int(const char *const **argv) {
+  const char *arg= pa_1arg(argv);
+  char *ep;
+  long l;
+
+  l= strtol(arg,&ep,0);
+  if (ep==arg || *ep) badusage("syntactically incorrect numeric input value");
+  return l;
+}
+static unsigned char pa_uc(const char *const **argv) {
+  long l= pa_int(argv);
+  if (l<-128 || l>255) badusage("input unsigned char out of range");
+  return (unsigned long)l;
+}
+  
+static void parse_none(const char *const **argv) { }
+static void parse_int(const char *const **argv) {
+  long l= pa_int(argv);
+  if (l<INT_MIN || l>INT_MAX) badusage("input int out of range");
+  parm.i= l;
+}
+static void parse_uc(const char *const **argv) {
+  parm.uc= pa_uc(argv);
+}
+static void parse_ppdfs(const char *const **argv) {
+  parm.fs.mask= pa_uc(argv);
+  parm.fs.val= pa_uc(argv);
+}
+static void parse_get(const char *const **argv) { }
+static void parse_mode(const char *const **argv) {
+  const char *arg= pa_1arg(argv);
+  const struct numvalinfo *mi;
+  FIND(mi, modeinfos, "mode name");
+  parm.i= mi->num;
+}
+
+static void print_none(void) { }
+static void print_int(void) { printf("%d\n",parm.i); }
+static void print_uc(void) { printf("0x%02x\n",parm.uc); }
+static void print_hex(void) {
+  const unsigned char *p;
+  for (p= (void*)&parm;
+       p < (const unsigned char*)(&parm + 1);
+       p++)
+    printf("0x%02x",*p);
+  putchar('\n');
+}
+static void print_mode(void) {
+  const struct numvalinfo *mi;
+  for (mi= modeinfos; mi->name && mi->num != parm.i; mi++);
+  if (mi->name) printf("%s\n",mi->name);
+  else printf("unknown mode 0x%x\n",parm.i);
+}
+static void print_dump(void) {
+  const struct typeinfo *ti;
+  for (ti= typeinfos; ti->name; ti++) {
+    if (!ti->print || ti->print==print_dump || ti->print==print_none) continue;
+    printf("%s\t", ti->name);
+    ti->print();
+  }
+}
+
+static const struct typeinfo typeinfos[] = {
+#define T(x) { #x, parse_##x, print_##x },
+#define TI(x) { #x, parse_##x, 0 },
+#define TO(x) { #x, 0, print_##x },
+  T(none)
+  T(int)
+  T(uc)
+  T(mode)
+  TI(ppdfs)
+  TI(get)
+  TO(hex)
+  TO(dump)
+  { 0 }
+};
+
+#define FINDT(v, d, n) do {                            \
+    FIND((v), typeinfos, "type for " d);               \
+    if (!(v)->n) badusage("unsupported type for " d);  \
+  }while(0)
+    
+int main(int argc, const char *const *argv) {
+  const struct numvalinfo *ioi;
+  const struct typeinfo *iti, *oti;
+  const char *arg;
+  int r;
+  
+  if (!*argv++) badusage("need argv[0]");
+  if (!(arg= *argv++)) badusage("need ioctl name");
+  if (arg[0] == '-') badusage("no options supported");
+  FIND(ioi, ioctlinfos, "ioctl name");
+
+  memset(&parm,0,sizeof(parm));
+  if ((arg= *argv)) {
+    argv++;
+    FINDT(iti, "input to ioctl", parse);
+    iti->parse(&argv);
+  }
+  if ((arg= *argv)) {
+    argv++;
+    FINDT(oti, "type for output from ioctl", print);
+  } else {
+    oti= 0;
+  }
+  if (*argv) badusage("too many args");
+
+  r= ioctl(0, ioi->num, &parm);
+  if (r<0) { perror("parport-ctl: ioctl failed"); exit(-1); }
+  if (r>0) { fprintf(stderr,"parport-ctl: ioctl gave %d!\n",r); }
+
+  if (oti) {
+    oti->print();
+    if (ferror(stdout)) { perror("parport-ctl: write stdout"); exit(-1); }
+  }
+  
+  return r>125 ? 125 : r;
+}