Exemplo n.º 1
0
SANE_Status	tcp_dev_open (struct device *dev)
{
    SANE_Status 	status;
    char*		strhost;
    char*		strport;
    int			port;
    struct		servent *sp;
    struct		timeval tv;
    SANE_String_Const	devname;


    devname = dev->sane.name;
    DBG (3, "%s: open %s\n", __FUNCTION__, devname);

    if (strncmp (devname, "tcp", 3) != 0)	return SANE_STATUS_INVAL;
    devname += 3;
    devname = sanei_config_skip_whitespace (devname);
    if (!*devname)	return SANE_STATUS_INVAL;

    devname = sanei_config_get_string (devname, &strhost);
    devname = sanei_config_skip_whitespace (devname);

    if (*devname)
	devname = sanei_config_get_string (devname, &strport);
    else
	strport = "9400";


    if (isdigit(*strport)) {
	port = atoi(strport);
    } else {
	if ((sp = getservbyname(strport, "tcp"))) {
	    port = ntohs(sp->s_port);
	} else {
	    DBG (1, "%s: unknown TCP service %s\n", __FUNCTION__, strport);
	    return SANE_STATUS_IO_ERROR;
	}
    }

    status = sanei_tcp_open(strhost, port, &dev->dn);
    if (status == SANE_STATUS_GOOD) {
	tv.tv_sec  = RECV_TIMEOUT;
	tv.tv_usec = 0;
	if (setsockopt (dev->dn, SOL_SOCKET, SO_RCVTIMEO, (char *)&tv, sizeof tv) < 0) {
	    DBG(1, "%s: setsockopts %s", __FUNCTION__, strerror(errno));
	}
    }

    return status;
}
Exemplo n.º 2
0
const char *
sanei_config_get_string (const char *str, char **string_const)
{
  const char *start;
  size_t len;

  str = sanei_config_skip_whitespace (str);

  if (*str == '"')
    {
      start = ++str;
      while (*str && *str != '"')
	++str;
      len = str - start;
      if (*str == '"')
	++str;
      else
	start = 0;		/* final double quote is missing */
    }
  else
    {
      start = str;
      while (*str && !isspace (*str))
	++str;
      len = str - start;
    }
  if (start)
    *string_const = strndup (start, len);
  else
    *string_const = 0;
  return str;
}
Exemplo n.º 3
0
SANE_Status
sane_init( SANE_Int *versionP, SANE_Auth_Callback authorize )
{
	FILE *fp;
	SANE_Status status;

	DBG_INIT();
	DBG(DCODE, "sane_init: version %s null, authorize %s null\n", (versionP) ? "!=" : "==", (authorize) ? "!=" : "==");

	if( versionP != NULL )
		*versionP = SANE_VERSION_CODE(SANE_CURRENT_MAJOR, V_MINOR, 0);

	status = SANE_STATUS_GOOD;
	if( (fp = sanei_config_open(ST400_CONFIG_FILE)) != NULL ) {
		char line[PATH_MAX], *str;
		size_t len, linenum;

		linenum = 0;
		DBG(DCODE, "sane_init: reading config file\n");
		while( sanei_config_read(line, sizeof(line), fp) ) {
			++linenum;
			str = line;
			if( str[0] == '#' )
				continue;	/* ignore comments */
			str = (char *)sanei_config_skip_whitespace(str);
			len = strlen(str);
			if( !len )
				continue;	/* ignore empty lines */
			if( strncmp(str, "option", 6) == 0 && isspace(str[6]) ) {
				DBG(DCODE, "sane_init: config line <%s>\n", line);
				status = st400_config_do_option(str+7, linenum);
			}
			else {
				DBG(DCODE, "sane_init: attaching device <%s>\n", line);
				sanei_config_attach_matching_devices(line, st400_attach_one);
			}
			if( status != SANE_STATUS_GOOD )
				break;
		}
		DBG(DCODE, "sane_init: closing config file\n");
		fclose(fp);
	}

	if( status == SANE_STATUS_GOOD && st400_devices == NULL ) {
		DBG(DCODE, "sane_init: attaching default device <%s>\n", ST400_DEFAULT_DEVICE);
		sanei_config_attach_matching_devices(ST400_DEFAULT_DEVICE, st400_attach_one);
	}

	return status;
}
Exemplo n.º 4
0
static SANE_Status
st400_config_get_arg(char **optP, unsigned long *argP, size_t linenum)
{
	int n;

	linenum = linenum; /* silence compilation warnings */

	if( sscanf(*optP, "%lu%n", argP, &n) == 1 ) {
		*optP += n;
		*optP = (char *)sanei_config_skip_whitespace(*optP);
		return SANE_STATUS_GOOD;
	}
	return SANE_STATUS_INVAL;
}
Exemplo n.º 5
0
static SANE_Status
st400_config_get_single_arg(char *opt, unsigned long *argP, size_t linenum)
{
	int n;

	if( sscanf(opt, "%lu%n", argP, &n) == 1 ) {
		opt += n;
		opt = (char *)sanei_config_skip_whitespace(opt);
		if( *opt == '\0' )
			return SANE_STATUS_GOOD;
		else {
			DBG(DERR, "extraneous arguments at line %lu: %s\n", (u_long)linenum, opt);
			return SANE_STATUS_INVAL;
		}
	}
	DBG(DERR, "invalid option argument at line %lu: %s\n", (u_long)linenum, opt);
	return SANE_STATUS_INVAL;
}
Exemplo n.º 6
0
/*
 * Called by SANE to find out about supported devices.
 * 
 * From the SANE spec:
 * This function can be used to query the list of devices that are
 * available. If the function executes successfully, it stores a
 * pointer to a NULL terminated array of pointers to SANE_Device
 * structures in *device_list. The returned list is guaranteed to
 * remain unchanged and valid until (a) another call to this function
 * is performed or (b) a call to sane_exit() is performed. This
 * function can be called repeatedly to detect when new devices become
 * available. If argument local_only is true, only local devices are
 * returned (devices directly attached to the machine that SANE is
 * running on). If it is false, the device list includes all remote
 * devices that are accessible to the SANE library.
 * 
 * SANE does not require that this function is called before a
 * sane_open() call is performed. A device name may be specified
 * explicitly by a user which would make it unnecessary and
 * undesirable to call this function first.
 *
 * Read the config file, find scanners with help from sanei_*
 * store in global device structs
 */
SANE_Status
sane_get_devices (const SANE_Device *** device_list, SANE_Bool local_only)
{
    struct scanner *dev;
    char line[PATH_MAX];
    const char *lp;
    FILE *fp;
    int num_devices=0;
    int i=0;
  
    local_only = local_only;        /* get rid of compiler warning */
  
    DBG (10, "sane_get_devices: start\n");
 
    global_has_cal_buffer = 1;
    global_lines_per_block = 16;

    fp = sanei_config_open (CONFIG_FILE);
  
    if (fp) {
  
        DBG (15, "sane_get_devices: reading config file %s\n", CONFIG_FILE);
  
        while (sanei_config_read (line, PATH_MAX, fp)) {
      
            lp = line;

            /* ignore comments */
            if (*lp == '#')
                continue;
      
            /* skip empty lines */
            if (*lp == 0)
                continue;
      
            if ((strncmp ("usb", lp, 3) == 0) && isspace (lp[3])) {
                DBG (15, "sane_get_devices: looking for '%s'\n", lp);
                sanei_usb_attach_matching_devices(lp, attach_one);
            }

            else if (!strncmp(lp, "has_cal_buffer", 14) && isspace (lp[14])) {
    
                int buf;
                lp += 14;
                lp = sanei_config_skip_whitespace (lp);
                buf = atoi (lp);
    
                if(buf){
                  global_has_cal_buffer = 1;
                }
                else{
                  global_has_cal_buffer = 0;
                }
    
                DBG (15, "sane_get_devices: setting \"has_cal_buffer\" to %d\n",
                  global_has_cal_buffer);
            }

            else if (!strncmp(lp, "lines_per_block", 15) && isspace (lp[15])) {
    
                int buf;
                lp += 15;
                lp = sanei_config_skip_whitespace (lp);
                buf = atoi (lp);
    
                if(buf < 1 || buf > 32){
                  DBG (15, 
                    "sane_get_devices: \"lines_per_block\"=%d\n out of range",
                    buf
                  );
                  continue;
                }

                DBG (15, "sane_get_devices: \"lines_per_block\" is %d\n", buf);
                global_lines_per_block = buf;
            }

            else{
                DBG (5, "sane_get_devices: config line \"%s\" ignored.\n", lp);
            }
        }
        fclose (fp);
    }
  
    else {
        DBG (5, "sane_get_devices: no config file '%s', using defaults\n",
          CONFIG_FILE);
  
        DBG (15, "sane_get_devices: looking for 'usb 0x08F0 0x0005'\n");
        sanei_usb_attach_matching_devices("usb 0x08F0 0x0005", attach_one);
    }
  
    for (dev = scanner_devList; dev; dev=dev->next) {
        DBG (15, "sane_get_devices: found scanner %s\n",dev->device_name);
        num_devices++;
    }
  
    DBG (15, "sane_get_devices: found %d scanner(s)\n",num_devices);
  
    sane_devArray = calloc (num_devices + 1, sizeof (SANE_Device*));
    if (!sane_devArray)
        return SANE_STATUS_NO_MEM;
  
    for (dev = scanner_devList; dev; dev=dev->next) {
        sane_devArray[i++] = (SANE_Device *)&dev->sane;
    }
  
    sane_devArray[i] = 0;
  
    *device_list = sane_devArray;
  
    DBG (10, "sane_get_devices: finish\n");
  
    return SANE_STATUS_GOOD;
}
Exemplo n.º 7
0
static SANE_Status
st400_config_do_option(char *opt, size_t linenum)
{
	unsigned long arg;
	SANE_Status status;
	int i;

	status = SANE_STATUS_GOOD;

	opt = (char *)sanei_config_skip_whitespace(opt);
	if( strncmp(opt, "maxread", 7) == 0 && isspace(opt[7]) ) {
		opt += 8;
		status = st400_config_get_single_arg(opt, &arg, linenum);
		if( status == SANE_STATUS_GOOD ) {
			if( arg == 0 )
				st400_maxread = sanei_scsi_max_request_size;
			else
				st400_maxread = (size_t)arg;
		}
	}
	else
	if( strncmp(opt, "delay", 5) == 0 && isspace(opt[5]) ) {
		opt += 6;
		status = st400_config_get_single_arg(opt, &arg, linenum);
		if( status == SANE_STATUS_GOOD )
			st400_light_delay = (size_t)arg;
	}
	else
	if( strncmp(opt, "scanner_bufsize", 15) == 0 && isspace(opt[15]) ) {
		opt += 16;
		status = st400_config_get_single_arg(opt, &arg, linenum);
		if( status == SANE_STATUS_GOOD )
			if( st400_devices )
				st400_devices->model->bufsize = arg;	/* FIXME: changes bufsize for all scanners of this model! */
	}
	else
	if( strncmp(opt, "scanner_bits", 12) == 0 && isspace(opt[12]) ) {
		opt += 13;
		status = st400_config_get_single_arg(opt, &arg, linenum);
		if( status == SANE_STATUS_GOOD )
			if( st400_devices )
				st400_devices->model->bits = arg;	/* FIXME */
	}
	else
	if( strncmp(opt, "scanner_maxread", 15) == 0 && isspace(opt[15]) ) {
		opt += 16;
		status = st400_config_get_single_arg(opt, &arg, linenum);
		if( status == SANE_STATUS_GOOD )
			if( st400_devices )
				st400_devices->model->maxread = arg;	/* FIXME */
	}
	else
	if( strncmp(opt, "scanner_resolutions", 19) == 0 && isspace(opt[19]) ) {
		opt += 20;
		st400_devices->model->dpi_list = malloc(16 * sizeof(SANE_Int));
		i = 0;
		do {
			status = st400_config_get_arg(&opt, &arg, linenum);
			if( status == SANE_STATUS_GOOD ) {
				++i;
				st400_devices->model->dpi_list[i] = (SANE_Int)arg;
			}
		} while( status == SANE_STATUS_GOOD && i < 15 );
		st400_devices->model->dpi_list[0] = i;
		DBG(DINFO, "%d entries for resolution\n", i);
		status = SANE_STATUS_GOOD;
	}
	else
	if( strncmp(opt, "dump_inquiry", 12) == 0 ) {
		st400_dump_data = 1;
	}
	if( st400_devices )
		st400_reset_options(st400_devices);
	return status;
}
Exemplo n.º 8
0
static void
add_alias (char *line)
{
  const char *command;
  enum { CMD_ALIAS, CMD_HIDE } cmd;
  const char *oldname, *oldend, *newname, *newend;
  size_t oldlen, newlen;
  struct alias *alias;

  command = sanei_config_skip_whitespace(line);
  if( !*command )
    return;
  line = strpbrk(command, " \t");
  if( !line )
    return;
  *line++ = '\0';

  if( strcmp(command, "alias") == 0 )
    cmd = CMD_ALIAS;
  else
  if( strcmp(command, "hide") == 0 )
    cmd = CMD_HIDE;
  else
    return;

  newlen = 0;
  newname = NULL;
  if( cmd == CMD_ALIAS )
    {
      newname = sanei_config_skip_whitespace(line);
      if( !*newname )
        return;
      if( *newname == '\"' )
        {
          ++newname;
          newend = strchr(newname, '\"');
        }
      else
          newend = strpbrk(newname, " \t");
      if( !newend )
        return;

      newlen = newend - newname;
      line = (char*)(newend+1);
    }

  oldname = sanei_config_skip_whitespace(line);
  if( !*oldname )
    return;
  oldend = oldname + strcspn(oldname, " \t");

  oldlen = oldend - oldname;

  alias = malloc(sizeof(struct alias));
  if( alias )
    {
      alias->oldname = malloc(oldlen + newlen + 2);
      if( alias->oldname )
        {
          strncpy(alias->oldname, oldname, oldlen);
          alias->oldname[oldlen] = '\0';
          if( cmd == CMD_ALIAS )
            {
              alias->newname = alias->oldname + oldlen + 1;
              strncpy(alias->newname, newname, newlen);
              alias->newname[newlen] = '\0';
            }
          else
              alias->newname = NULL;

          alias->next = first_alias;
          first_alias = alias;
          return;
        }
      free(alias);
    }
  return;
}
Exemplo n.º 9
0
SANE_Status
sanei_configure_attach (const char *config_file, SANEI_Config * config,
			SANE_Status (*attach) (SANEI_Config * config,
					       const char *devname))
{
  SANE_Char line[PATH_MAX];
  SANE_Char *token, *string;
  SANE_Int len;
  const char *lp, *lp2;
  FILE *fp;
  SANE_Status status = SANE_STATUS_GOOD;
  int i, j, count;
  void *value = NULL;
  int size=0;
  SANE_Bool found;
  SANE_Word *wa;
  SANE_Bool *ba;

  DBG (3, "sanei_configure_attach: start\n");

  /* open configuration file */
  fp = sanei_config_open (config_file);
  if (!fp)
    {
      DBG (2, "sanei_configure_attach: couldn't access %s\n", config_file);
      DBG (3, "sanei_configure_attach: exit\n");
      return SANE_STATUS_ACCESS_DENIED;
    }

  /* loop reading the configuration file, all line beginning by "option " are
   * parsed for value to store in configuration structure, other line are 
   * used are device to try to attach
   */
  while (sanei_config_read (line, PATH_MAX, fp) && status == SANE_STATUS_GOOD)
    {
      /* skip white spaces at beginning of line */
      lp = sanei_config_skip_whitespace (line);

      /* skip empty lines */
      if (*lp == 0)
	continue;

      /* skip comment line */
      if (line[0] == '#')
	continue;

      len = strlen (line);

      /* delete newline characters at end */
      if (line[len - 1] == '\n')
	line[--len] = '\0';

      lp2 = lp;

      /* to ensure maximum compatibility, we accept line like:
       * option "option_name" "option_value"
       * "option_name" "option_value" 
       * So we parse the line 2 time to find an option */
      /* check if it is an option */
      lp = sanei_config_get_string (lp, &token);
      if (strncmp (token, "option", 6) == 0)
	{
	  /* skip the "option" token */
	  free (token);
	  lp = sanei_config_get_string (lp, &token);
	}

      /* search for a matching descriptor */
      i = 0;
      found = SANE_FALSE;
      while (config!=NULL && i < config->count && !found)
	{
	  if (strcmp (config->descriptors[i]->name, token) == 0)
	    {
	      found = SANE_TRUE;
	      switch (config->descriptors[i]->type)
		{
		case SANE_TYPE_INT:
		  size=config->descriptors[i]->size;
		  value = malloc (size);
		  wa = (SANE_Word *) value;
		  count = config->descriptors[i]->size / sizeof (SANE_Word);
		  for (j = 0; j < count; j++)
		    {
		      lp = sanei_config_get_string (lp, &string);
		      if (string == NULL)
			{
			  DBG (2,
			       "sanei_configure_attach: couldn't find a string to parse");
			  return SANE_STATUS_INVAL;
			}
		      wa[j] = strtol (string, NULL, 0);
		      free (string);
		    }
		  break;
		case SANE_TYPE_BOOL:
		  size=config->descriptors[i]->size;
		  value = malloc (size);
		  ba = (SANE_Bool *) value;
		  count = config->descriptors[i]->size / sizeof (SANE_Bool);
		  for (j = 0; j < count; j++)
		    {
		      lp = sanei_config_get_string (lp, &string);
		      if (string == NULL)
			{
			  DBG (2,
			       "sanei_configure_attach: couldn't find a string to parse");
			  return SANE_STATUS_INVAL;
			}
		      if ((strcmp (string, "1") == 0)
			  || (strcmp (string, "true") == 0))
			{
			  ba[j] = SANE_TRUE;
			}
		      else
			{
			  if ((strcmp (string, "0") == 0)
			      || (strcmp (string, "false") == 0))
			    ba[j] = SANE_FALSE;
			  else
			    {
			      DBG (2,
				   "sanei_configure_attach: couldn't find a valid boolean value");
			      return SANE_STATUS_INVAL;
			    }
			}
		      free (string);
		    }
		  break;
		case SANE_TYPE_FIXED:
		  size=config->descriptors[i]->size;
		  value = malloc (size);
		  wa = (SANE_Word *) value;
		  count = config->descriptors[i]->size / sizeof (SANE_Word);
		  for (j = 0; j < count; j++)
		    {
		      lp = sanei_config_get_string (lp, &string);
		      if (string == NULL)
			{
			  DBG (2,
			       "sanei_configure_attach: couldn't find a string to parse");
			  return SANE_STATUS_INVAL;
			}
		      wa[j] = SANE_FIX(strtod (string, NULL));
		      free (string);
		    }
		  break;
		case SANE_TYPE_STRING:
		  sanei_config_get_string (lp, &string);
		  if (string == NULL)
		    {
		      DBG (2,
			   "sanei_configure_attach: couldn't find a string value to parse");
		      return SANE_STATUS_INVAL;
		    }
		  value = string;
		  size=strlen(string)+1;
		  if(size>config->descriptors[i]->size)
		  {
			  size=config->descriptors[i]->size-1;
			  string[size]=0;
		  }
		  break;
		default:
		  DBG (1,
		       "sanei_configure_attach: incorrect type %d for option %s, skipping option ...\n",
		       config->descriptors[i]->type,
		       config->descriptors[i]->name);
		}
	      
	      /* check decoded value */
	      status = sanei_check_value (config->descriptors[i], value);

	      /* if value OK, copy it in configuration struct */
	      if (status == SANE_STATUS_GOOD)
		{
		  memcpy (config->values[i], value, size);
		}
	      if (value != NULL)
		{
		  free (value);
		  value = NULL;
		}
	    }
	  if (status != SANE_STATUS_GOOD)
	    {
	      DBG (1,
		   "sanei_configure_attach: failed to parse option '%s', line '%s'\n",
		   token, line);
	    }
	  i++;
	}
      free (token);

      /* not detected as an option, so we call the attach function
       * with it */
      if (!found && status == SANE_STATUS_GOOD)
	{
	  /* if not an option, try to attach */
	  /* to avoid every backend to depend on scsi and usb functions
	   * we call back the backend for attach. In turn it will call
	   * sanei_usb_attach_matching_devices, sanei_config_attach_matching_devices
	   * or other. This means 2 callback functions per backend using this 
	   * function. */
	  DBG (3, "sanei_configure_attach: trying to attach with '%s'\n",
	       lp2);
	  if(attach!=NULL)
	  	attach (config, lp2);
	}
    }

  fclose (fp);
  DBG (3, "sanei_configure_attach: exit\n");
  return status;
}