• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2    off.c - Switch the Mustek 600 II N off
3 
4    This utility accesses the I/O-ports directly and must therefore be
5    run with euid root, or must at least have access to /dev/port.
6    Compile with:
7    gcc -DHAVE_SYS_IO_H -O2 -Wall -s -o off off.c
8    The -O2 optimization is needed to allow inline functions !
9    Copyright (C) 1997-1999 Andreas Czechanowski, DL4SDC
10 
11    This program is free software; you can redistribute it and/or modify
12    it under the terms of the GNU General Public License as published by
13    the Free Software Foundation; either version 2 of the License, or
14    (at your option) any later version.
15 
16    This program is distributed in the hope that it will be useful,
17    but WITHOUT ANY WARRANTY; without even the implied warranty of
18    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19    GNU General Public License for more details.
20 
21    You should have received a copy of the GNU General Public License
22    along with this program.  If not, see <https://www.gnu.org/licenses/>.
23 
24    andreas.czechanowski@ins.uni-stuttgart.de
25  */
26 
27 #include "../include/sane/config.h"
28 #include "../include/sane/sanei.h"
29 #include "../include/sane/sanei_directio.h"
30 
31 #define MUSTEK_CONF	STRINGIFY(PATH_SANE_CONFIG_DIR) "/mustek.conf"
32 #define PORT_DEV	"/dev/port"
33 
34 #include <stdio.h>
35 #include <stdlib.h>
36 #include <fcntl.h>
37 #include <string.h>
38 #include <unistd.h>
39 
40 #include <sys/types.h>
41 #include <sys/stat.h>
42 
43 char *Mustek_Conf = MUSTEK_CONF;
44 
45 int allowed_ports[] =
46 {
47   0x26b, 0x26c,
48   0x2ab, 0x2ac,
49   0x2eb, 0x2ec,
50   0x22b, 0x22c,
51   0x32b, 0x32c,
52   0x36b, 0x36c,
53   0x3ab, 0x3ac,
54   0x3eb, 0x3ec,
55   -1
56 };
57 
58 void
usage(void)59 usage (void)
60 {
61   fprintf (stderr, "Usage: off [port]\n"
62 	   "  switches the Mustek 600 II N off that is connected to\n"
63 	   "  base address <port>. If address is not given, reads it\n"
64 	   "  from SANE config file <%s>.\n", Mustek_Conf);
65 }
66 
67 void
noaccess(int portaddr)68 noaccess (int portaddr)
69 {
70   fprintf (stderr, "Access to port 0x%03x not allowed !\n", portaddr);
71 }
72 
73 int
check_port(int portaddr)74 check_port (int portaddr)
75 {
76   int i, j;
77 
78   for (i = 0; (j = allowed_ports[i]) != -1; i++)
79     {
80       if (j == portaddr)
81 	return j;
82     }
83   return -1;
84 }
85 
86 int
str2int(char * ch)87 str2int (char *ch)
88 {
89   int i;
90 
91   i = strtol (ch, NULL, 0);
92   return i;
93 }
94 
95 int
main(int argc,char ** argv)96 main (int argc, char **argv)
97 {
98   char *cp;
99   int portaddr = 0;
100   FILE *fp;
101   int pfd;
102 
103   /* get config file name from environment if variable is set */
104   if (NULL != (cp = getenv ("MUSTEK_CONF")))
105     {
106       Mustek_Conf = cp;
107     }
108 
109   /* if port is explicitly given, try this one */
110   if (argc > 1)
111     {
112       portaddr = str2int (argv[1]);
113     }
114   /* else try to look it up from SANE's mustek.conf file */
115   else if (NULL != (fp = fopen (MUSTEK_CONF, "r")))
116     {
117       char line[256];
118 
119       while (NULL != fgets (line, 255, fp))
120 	{
121 	  if ('#' == *line)
122 	    continue;
123 	  if (0 != (portaddr = str2int (line)))
124 	    break;
125 	}
126       fclose (fp);
127     }
128   else
129     {
130       fprintf (stderr, "Mustek config file <%s> not found\n", Mustek_Conf);
131       usage ();
132       exit (1);
133     }
134 
135   if (check_port (portaddr) < 0 || check_port (portaddr + 1) < 0)
136     {
137       fprintf (stderr, "invalid port address specified !\n");
138       usage ();
139       exit (1);
140     }
141 
142   /* we need the control port, not the data port, so... */
143   portaddr++;
144 
145   fprintf (stderr, "using control port address 0x%03x\n", portaddr);
146   /* try to get I/O permission from the kernel */
147   if (sanei_ioperm (portaddr, 1, 1) == 0)
148     {
149       sanei_outb (portaddr, 0x00);
150     }
151   /* else try to open /dev/port to access the I/O port */
152   else if ((pfd = open (PORT_DEV, O_RDWR, 0666)) >= 0)
153     {
154       char offcmd[] =
155       {0x00};
156 
157       if ((lseek (pfd, portaddr, SEEK_SET) != portaddr)
158 	  || (write (pfd, offcmd, 1) != 1))
159 	{
160 	  perror ("error handling /dev/port");
161 	  exit (1);
162 	}
163       close (pfd);
164     }
165   else
166     {
167       fprintf (stderr, "Could not get port access:\n"
168 	       "Neither via ioperm(), nor via /dev/port.\n"
169 	       "This program must be run setuid root,\n"
170 	       "or the user must have access to /dev/port.\n");
171       exit (1);
172     }
173   printf ("successfully sent OFF-command to control port at 0x%03x.\n",
174 	  portaddr);
175 
176   exit (0);
177 }
178