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