kopia lustrzana https://gitlab.com/sane-project/backends
				
				
				
			
		
			
				
	
	
		
			200 wiersze
		
	
	
		
			4.5 KiB
		
	
	
	
		
			C
		
	
	
			
		
		
	
	
			200 wiersze
		
	
	
		
			4.5 KiB
		
	
	
	
		
			C
		
	
	
/*
 | 
						|
   off.c - Switch the Mustek 600 II N off
 | 
						|
 | 
						|
   This utility accesses the I/O-ports directly and must therefore be
 | 
						|
   run with euid root, or must at least have access to /dev/port.
 | 
						|
   Compile with:
 | 
						|
   gcc -DHAVE_SYS_IO_H -O2 -Wall -s -o off off.c
 | 
						|
   The -O2 optimization is needed to allow inline functions !
 | 
						|
   Copyright (C) 1997-1999 Andreas Czechanowski, DL4SDC
 | 
						|
 | 
						|
   This program is free software; you can redistribute it and/or modify
 | 
						|
   it under the terms of the GNU General Public License as published by
 | 
						|
   the Free Software Foundation; either version 2 of the License, or
 | 
						|
   (at your option) any later version.
 | 
						|
 | 
						|
   This program is distributed in the hope that it will be useful,
 | 
						|
   but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
						|
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
						|
   GNU General Public License for more details.
 | 
						|
 | 
						|
   You should have received a copy of the GNU General Public License
 | 
						|
   along with this program; if not, write to the Free Software Foundation,
 | 
						|
   Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 | 
						|
 | 
						|
   andreas.czechanowski@ins.uni-stuttgart.de
 | 
						|
 */
 | 
						|
 | 
						|
#include "../include/sane/config.h"
 | 
						|
#include "../include/sane/sanei.h"
 | 
						|
 | 
						|
#define MUSTEK_CONF	STRINGIFY(PATH_SANE_CONFIG_DIR) "/mustek.conf"
 | 
						|
#define PORT_DEV	"/dev/port"
 | 
						|
 | 
						|
#include <stdio.h>
 | 
						|
#include <stdlib.h>
 | 
						|
#include <fcntl.h>
 | 
						|
#include <string.h>
 | 
						|
#include <unistd.h>
 | 
						|
 | 
						|
#include <sys/types.h>
 | 
						|
#include <sys/stat.h>
 | 
						|
 | 
						|
#ifdef HAVE_SYS_IO_H
 | 
						|
# include <sys/io.h>	/* use where available (glibc 2.x, for example) */
 | 
						|
#elif HAVE_ASM_IO_H
 | 
						|
# include <asm/io.h>	/* ugly, but backwards compatible */
 | 
						|
#elif defined(__i386__)  && defined (__GNUC__)
 | 
						|
 | 
						|
static __inline__ void
 | 
						|
outb (u_char value, u_long port)
 | 
						|
{
 | 
						|
  __asm__ __volatile__ ("outb %0,%1"::"a" (value), "d" ((u_short) port));
 | 
						|
}
 | 
						|
 | 
						|
static __inline__ u_char
 | 
						|
inb (u_long port)
 | 
						|
{
 | 
						|
  u_char value;
 | 
						|
 | 
						|
  __asm__ __volatile__ ("inb %1,%0":"=a" (value):"d" ((u_short) port));
 | 
						|
  return value;
 | 
						|
}
 | 
						|
#endif
 | 
						|
 | 
						|
char *Mustek_Conf = MUSTEK_CONF;
 | 
						|
 | 
						|
int allowed_ports[] =
 | 
						|
{
 | 
						|
  0x26b, 0x26c,
 | 
						|
  0x2ab, 0x2ac,
 | 
						|
  0x2eb, 0x2ec,
 | 
						|
  0x22b, 0x22c,
 | 
						|
  0x32b, 0x32c,
 | 
						|
  0x36b, 0x36c,
 | 
						|
  0x3ab, 0x3ac,
 | 
						|
  0x3eb, 0x3ec,
 | 
						|
  -1
 | 
						|
};
 | 
						|
 | 
						|
void
 | 
						|
usage (void)
 | 
						|
{
 | 
						|
  fprintf (stderr, "Usage: off [port]\n"
 | 
						|
	   "  switches the Mustek 600 II N off that is connected to\n"
 | 
						|
	   "  base address <port>. If address is not given, reads it\n"
 | 
						|
	   "  from SANE config file <%s>.\n", Mustek_Conf);
 | 
						|
}
 | 
						|
 | 
						|
void
 | 
						|
noaccess (int portaddr)
 | 
						|
{
 | 
						|
  fprintf (stderr, "Access to port 0x%03x not allowed !\n", portaddr);
 | 
						|
}
 | 
						|
 | 
						|
int
 | 
						|
check_port (int portaddr)
 | 
						|
{
 | 
						|
  int i, j;
 | 
						|
 | 
						|
  for (i = 0; (j = allowed_ports[i]) != -1; i++)
 | 
						|
    {
 | 
						|
      if (j == portaddr)
 | 
						|
	return j;
 | 
						|
    }
 | 
						|
  return -1;
 | 
						|
}
 | 
						|
 | 
						|
int
 | 
						|
str2int (char *ch)
 | 
						|
{
 | 
						|
  int i;
 | 
						|
 | 
						|
  i = strtol (ch, NULL, 0);
 | 
						|
  return i;
 | 
						|
}
 | 
						|
 | 
						|
int
 | 
						|
main (int argc, char **argv)
 | 
						|
{
 | 
						|
  char *cp;
 | 
						|
  int portaddr = 0;
 | 
						|
  FILE *fp;
 | 
						|
  int pfd;
 | 
						|
 | 
						|
  /* get config file name from environment if variable is set */
 | 
						|
  if (NULL != (cp = getenv ("MUSTEK_CONF")))
 | 
						|
    {
 | 
						|
      Mustek_Conf = cp;
 | 
						|
    }
 | 
						|
 | 
						|
  /* if port is explicitly given, try this one */
 | 
						|
  if (argc > 1)
 | 
						|
    {
 | 
						|
      portaddr = str2int (argv[1]);
 | 
						|
    }
 | 
						|
  /* else try to look it up from SANE's mustek.conf file */
 | 
						|
  else if (NULL != (fp = fopen (MUSTEK_CONF, "r")))
 | 
						|
    {
 | 
						|
      char line[256];
 | 
						|
 | 
						|
      while (NULL != fgets (line, 255, fp))
 | 
						|
	{
 | 
						|
	  if ('#' == *line)
 | 
						|
	    continue;
 | 
						|
	  if (0 != (portaddr = str2int (line)))
 | 
						|
	    break;
 | 
						|
	}
 | 
						|
      fclose (fp);
 | 
						|
    }
 | 
						|
  else
 | 
						|
    {
 | 
						|
      fprintf (stderr, "Mustek config file <%s> not found\n", Mustek_Conf);
 | 
						|
      usage ();
 | 
						|
      exit (1);
 | 
						|
    }
 | 
						|
 | 
						|
  if (check_port (portaddr) < 0 || check_port (portaddr + 1) < 0)
 | 
						|
    {
 | 
						|
      fprintf (stderr, "invalid port address specified !\n");
 | 
						|
      usage ();
 | 
						|
      exit (1);
 | 
						|
    }
 | 
						|
 | 
						|
  /* we need the control port, not the data port, so... */
 | 
						|
  portaddr++;
 | 
						|
 | 
						|
  fprintf (stderr, "using control port address 0x%03x\n", portaddr);
 | 
						|
  /* try to get I/O permission from the kernel */
 | 
						|
  if (ioperm (portaddr, 1, 1) == 0)
 | 
						|
    {
 | 
						|
      outb (0x00, portaddr);
 | 
						|
    }
 | 
						|
  /* else try to open /dev/port to access the I/O port */
 | 
						|
  else if ((pfd = open (PORT_DEV, O_RDWR, 0666)) >= 0)
 | 
						|
    {
 | 
						|
      char offcmd[] =
 | 
						|
      {0x00};
 | 
						|
 | 
						|
      if ((lseek (pfd, portaddr, SEEK_SET) != portaddr)
 | 
						|
	  || (write (pfd, offcmd, 1) != 1))
 | 
						|
	{
 | 
						|
	  perror ("error handling /dev/port");
 | 
						|
	  exit (1);
 | 
						|
	}
 | 
						|
      close (pfd);
 | 
						|
    }
 | 
						|
  else
 | 
						|
    {
 | 
						|
      fprintf (stderr, "Could not get port access:\n"
 | 
						|
	       "Neither via ioperm(), nor via /dev/port.\n"
 | 
						|
	       "This program must be run setuid root,\n"
 | 
						|
	       "or the user must have access to /dev/port.\n");
 | 
						|
      exit (1);
 | 
						|
    }
 | 
						|
  printf ("successfully sent OFF-command to control port at 0x%03x.\n",
 | 
						|
	  portaddr);
 | 
						|
 | 
						|
  exit (0);
 | 
						|
}
 |