Re: dll backend: aliased & hidden device names

From: Ingo Wilken (Ingo.Wilken@Informatik.Uni-Oldenburg.DE)
Date: Wed Jan 26 2000 - 14:40:31 PST

  • Next message: jes@presto.med.upenn.edu: "Re: Semi OT: SCSI termination question"

    Hi

    > I'm currently collecting SANE patches, and was planning to test your
    > dll alias patch. Unfortunately, the only version I have available is
    > <URL:http://www.mostang.com/mail-archive/sane-devel/1999-07/0007.html>,
    > which is filled with HTML tags. :-(
    > Could you send me the latest version of you patch, possibly relative
    > to the latest SANE CVS snapshot,
    > <URL:http://www.student.uit.no/~pere/linux/sane/sane-devel-20000123.tar.gz>?

    I did no further work on the aliases/hidden stuff. The old patch is
    appended below. I'll create a new patch relative to the CVS snapshot
    when I get it to my home machine (possibly next week - I'm currently only
    reading mail via a dead slow modem link and long distance call, so I'm not
    going to download anything larger than a few KB).

    For best results, there should be a modification to the SANE API so programs
    (and special backends like the net backend) can request unaliased device
    names in sane_get_devices(). It's a minor modification:
     SANE_Status sane_get_devices(const SANE_Device ***dev, SANE_Bool local_only)
    would become something like
     SANE_Status sane_get_devices(const SANE_Device ***dev, SANE_Flags flags)
    with two possible flags:
     #define SANEF_LOCAL_ONLY 0x01
     #define SANEF_UNALIASED 0x02

    Regards,
    Ingo

    --- my old mail with the patch: ---
    This is a first attempt to add device names aliases and hidden
    devices to the dll backend. It works ok here, so I'm releasing
    the patches and ask for your comments.

    Aliases are defined in the new config file "dll.aliases".
    This can contain entries of the form

            alias SomeName SaneDeviceName
            alias "Some Name" SaneDeviceName
            hide SaneDeviceName

    For example:

            alias Epson net:somehost:epson:/dev/sgX
            alias "Siemens ST400" st400:/dev/sgY
            hide net:somehost:pnm:0
            hide net:somehost:pnm:1
            alias "Read from file" pnm:0
            hide pnm:1

    Aliased device names are automatically hidden.

    The idea is that users don't have to deal with complicated device
    names (especially for networked devices), and to hide other exported
    devices which might confuse them. Note that a hidden device can still
    be accessed if the device name is known, it just doesn't appear on
    the list.

    Regards,
    Ingo

    *** dll.c.orig Tue Apr 27 06:35:12 1999
    --- dll.c Fri Jul 2 19:24:42 1999
    ***************
    *** 91,96 ****
    --- 91,97 ----
      
      #include <sane/sanei_config.h>
      #define DLL_CONFIG_FILE "dll.conf"
    + #define DLL_ALIASES_FILE "dll.aliases"
      
      enum SANE_Ops
        {
    ***************
    *** 170,175 ****
    --- 171,184 ----
          SANE_Handle handle;
        };
      
    + struct alias
    + {
    + struct alias *next;
    + char *oldname;
    + char *newname;
    + };
    +
    + static struct alias *first_alias;
      static SANE_Auth_Callback auth_callback;
      static struct backend *first_backend;
      static const char *op_name[] =
    ***************
    *** 302,308 ****
    --- 311,321 ----
      #endif /* HAVE_DLOPEN */
        if (!be->handle)
          {
    + #ifdef HAVE_DLOPEN
    + DBG(2, "dlopen() failed (%s)\n", dlerror ());
    + #else
            DBG(2, "dlopen() failed (%s)\n", strerror (errno));
    + #endif /* HAVE_DLOPEN */
            return SANE_STATUS_INVAL;
          }
      
    ***************
    *** 379,384 ****
    --- 392,478 ----
        return SANE_STATUS_GOOD;
      }
      
    +
    + 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;
    + }
    +
    +
      SANE_Status
      sane_init (SANE_Int * version_code, SANE_Auth_Callback authorize)
      {
    ***************
    *** 422,427 ****
    --- 516,539 ----
          }
        fclose (fp);
      
    + fp = sanei_config_open (DLL_ALIASES_FILE);
    + if (!fp)
    + return SANE_STATUS_GOOD; /* don't insist on aliases file */
    +
    + while (fgets (backend_name, sizeof (backend_name), fp))
    + {
    + if (backend_name[0] == '#') /* ignore line comments */
    + continue;
    + len = strlen (backend_name);
    + if (backend_name[len - 1] == '\n')
    + backend_name[--len] = '\0';
    +
    + if (!len)
    + continue; /* ignore empty lines */
    +
    + add_alias (backend_name);
    + }
    + fclose (fp);
        return SANE_STATUS_GOOD;
      }
      
    ***************
    *** 429,434 ****
    --- 541,547 ----
      sane_exit (void)
      {
        struct backend *be, *next;
    + struct alias *alias;
      
        DBG(1, "exiting\n");
      
    ***************
    *** 461,466 ****
    --- 574,586 ----
              }
          }
        first_backend = 0;
    +
    + while( (alias = first_alias) != NULL )
    + {
    + first_alias = first_alias->next;
    + free(alias->oldname);
    + free(alias);
    + }
      }
      
      /* Note that a call to get_devices() implies that we'll have to load
    ***************
    *** 517,535 ****
              {
                SANE_Device *dev;
                char *mem;
      
    ! /* create a new device entry with a device name that is the
    ! sum of the backend name a colon and the backend's device
    ! name: */
    ! len = strlen (be->name) + 1 + strlen (be_list[i]->name);
    ! mem = malloc (sizeof (*dev) + len + 1);
    ! if (!mem)
    ! return SANE_STATUS_NO_MEM;
    !
    ! full_name = mem + sizeof (*dev);
    ! strcpy (full_name, be->name);
    ! strcat (full_name, ":");
    ! strcat (full_name, be_list[i]->name);
      
                dev = (SANE_Device *) mem;
                dev->name = full_name;
    --- 637,683 ----
              {
                SANE_Device *dev;
                char *mem;
    + struct alias *alias;
      
    ! for(alias = first_alias; alias != NULL; alias = alias->next)
    ! {
    ! len = strlen(be->name);
    ! if( strlen(alias->oldname) <= len )
    ! continue;
    ! if( strncmp(alias->oldname, be->name, len) == 0
    ! && alias->oldname[len] == ':'
    ! && strcmp(&alias->oldname[len+1], be_list[i]->name) == 0 )
    ! break;
    ! }
    !
    ! if( alias )
    ! {
    ! if( !alias->newname ) /* hidden device */
    ! continue;
    !
    ! len = strlen(alias->newname);
    ! mem = malloc(sizeof(*dev) + len + 1);
    ! if( !mem )
    ! return SANE_STATUS_NO_MEM;
    !
    ! full_name = mem + sizeof(*dev);
    ! strcpy(full_name, alias->newname);
    ! }
    ! else
    ! {
    ! /* create a new device entry with a device name that is the
    ! sum of the backend name a colon and the backend's device
    ! name: */
    ! len = strlen (be->name) + 1 + strlen (be_list[i]->name);
    ! mem = malloc (sizeof (*dev) + len + 1);
    ! if (!mem)
    ! return SANE_STATUS_NO_MEM;
    !
    ! full_name = mem + sizeof (*dev);
    ! strcpy (full_name, be->name);
    ! strcat (full_name, ":");
    ! strcat (full_name, be_list[i]->name);
    ! }
      
                dev = (SANE_Device *) mem;
                dev->name = full_name;
    ***************
    *** 557,562 ****
    --- 705,722 ----
        SANE_Handle *handle;
        struct backend *be;
        SANE_Status status;
    + struct alias *alias;
    +
    + for( alias = first_alias; alias != NULL; alias = alias->next )
    + {
    + if( !alias->newname )
    + continue;
    + if( strcmp(alias->newname, full_name) == 0 )
    + {
    + full_name = alias->oldname;
    + break;
    + }
    + }
      
        dev_name = strchr (full_name, ':');
        if (dev_name)

    --
    Source code, list archive, and docs: http://www.mostang.com/sane/
    To unsubscribe: echo unsubscribe sane-devel | mail majordomo@mostang.com
    



    This archive was generated by hypermail 2b29 : Wed Jan 26 2000 - 14:39:38 PST