<div dir="ltr">So, I went ahead and gave this a try (specifically, option B) and it seems to work perfectly well (both via the scanimage commandline and gscan2pdf). I attempted to rig up enabling this with a flag, but couldn't grok how sane's flag system worked from just staring at the code. I've included the diff below in case it is helpful. For now, I'll leave my dodgy "one-random custom-built so-file" setup in place, but +1 for making this a mainline feature and thanks for the assistance. It is most appreciated.<div><br></div><div>-Guy<br><br><br><span style="font-family:monospace"><span style="font-weight:bold;color:rgb(0,0,0)">diff --git a/backend/net.c b/backend/net.c</span><span style="color:rgb(0,0,0)">
</span><br><span style="font-weight:bold;color:rgb(0,0,0)">index d16119a81..4acb92730 100644</span><span style="color:rgb(0,0,0)">
</span><br><span style="font-weight:bold;color:rgb(0,0,0)">--- a/backend/net.c</span><span style="color:rgb(0,0,0)">
</span><br><span style="font-weight:bold;color:rgb(0,0,0)">+++ b/backend/net.c</span><span style="color:rgb(0,0,0)">
</span><br><span style="color:rgb(24,178,178)">@@ -120,6 +120,7 @@</span><span style="color:rgb(0,0,0)"> static int client_big_endian; /* 1 == big endian; 0 == little endian */
</span><br> static int server_big_endian; /* 1 == big endian; 0 == little endian */
<br> static int depth; /* bits per pixel */
<br> static int connect_timeout = -1; /* timeout for connection to saned */
<br><span style="color:rgb(24,178,24)">+static SANE_Bool reshare_net = SANE_FALSE; /* if true, reshare network-connected */</span><span style="color:rgb(0,0,0)">
</span><br>  <br> #ifndef NET_USES_AF_INDEP
<br> static int saned_port;
<br><span style="color:rgb(24,178,178)">@@ -1117,6 +1118,14 @@</span><span style="color:rgb(0,0,0)"> sane_init (SANE_Int * version_code, SANE_Auth_Callback authorize)
</span><br>       DBG (2, "sane_init: connect timeout set to %d seconds from env\n", connect_timeout);
<br>     }
<br>  <br><span style="color:rgb(24,178,24)">+  DBG (2, "sane_init: evaluating environment variable SANE_NET_RESHARE\n");</span><span style="color:rgb(0,0,0)">
</span><br><span style="color:rgb(24,178,24)">+  env = getenv("SANE_NET_RESHARE");</span><span style="color:rgb(0,0,0)">
</span><br><span style="color:rgb(24,178,24)">+  if (env)</span><span style="color:rgb(0,0,0)">
</span><br><span style="color:rgb(24,178,24)">+    {</span><span style="color:rgb(0,0,0)">
</span><br><span style="color:rgb(24,178,24)">+      reshare_net = SANE_TRUE;</span><span style="color:rgb(0,0,0)">
</span><br><span style="color:rgb(24,178,24)">+      DBG (2, "sane_init: resharing of net scanners enabled\n");</span><span style="color:rgb(0,0,0)">
</span><br><span style="color:rgb(24,178,24)">+    }</span><span style="color:rgb(0,0,0)">
</span><br><span style="color:rgb(24,178,24)">+</span><span style="color:rgb(0,0,0)">
</span><br>   DBG (2, "sane_init: done\n");
<br>   return SANE_STATUS_GOOD;
<br> }
<br><span style="color:rgb(24,178,178)">@@ -1220,7 +1229,7 @@</span><span style="color:rgb(0,0,0)"> sane_get_devices (const SANE_Device *** device_list, SANE_Bool local_only)
</span><br>  <br>   DBG (3, "sane_get_devices: local_only = %d\n", local_only);
<br>  <br><span style="color:rgb(178,24,24)">-  if (local_only)</span><span style="color:rgb(0,0,0)">
</span><br><span style="color:rgb(24,178,24)">+  if (local_only && !reshare_net)</span><span style="color:rgb(0,0,0)">
</span><br>     {
<br>       *device_list = empty_devlist;
<br>       return SANE_STATUS_GOOD;<br></span></div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Sun, Aug 7, 2022 at 7:39 AM Ralph Little <<a href="mailto:skelband@gmail.com">skelband@gmail.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
  
    
  
  <div>
    Hi,<br>
    <br>
    <div>On 2022-08-02 12:46, Guy B wrote:<br>
    </div>
    <blockquote type="cite">
      
      <div dir="ltr">I'm trying to determine if this setup can actually
        be made to function (and Googling has given no obvious answer).<br>
        <br>
        Server A - connected to scanner via USB, exposed via network
        <div>      ↓<br>
          Server B - connected to A via the "net" interface, re-exposes
          scanner to another net via "net" interface<br>
               ↓<br>
          Server C - connects to B via "net"<br>
          <br>
          The reason that I'm trying to do this is because "A" in this
          use case is actually a VM running an ancient version of Ubuntu
          because that's the only place I can make the binary-only
          drivers work (and I don't want a 10+ year old version of
          Ubuntu exposed to <i>any</i> network). "B" is then a real
          machine that I want to use to expose it to the rest of the
          network.<br>
          <br>
          While I've had no trouble plumbing things through to "B", I
          can't figure out how (or if it is possible) to re-share the
          network scanner again.</div>
        <div><br>
        </div>
        <div>-Guy</div>
      </div>
    </blockquote>
    <br>
    So to summarise:<br>
        - Server A (VM) will be running the binary driver and saned,<br>
        - Server B will be running SANE with the "net" backend
    (configured to connect to Server A's saned) and also saned,<br>
        - Server C will be running SANE with the "net" backend
    (configured to connect to Server B's saned).<br>
    <br>
    Although this sounds reasonable, the only issue that I can see with
    this setup is that saned running on Server B will not pick up the
    devices through the "net" backend.<br>
    The reason for this is that saned is intended to advertise local
    devices only and when asking the "net" backend for local devices, it
    will simply return with an empty list.<br>
    Partly the reason for this is to stop deadly embrace loops where the
    "net" backend and saned could conceivably keep re-advertising each
    other's devices in an endless loop.<br>
    <br>
    Without changing code, I don't see an obvious way around this
    restriction. However, there are two ways you could get around this
    in your circumstance if you are willing do some minor code changes
    and rebuild.<br>
    <br>
    Do one of:<br>
    <br>
    A. Rebuild saned with a small change to the code here around line
    1851 of saned.c:<br>
    <br>
          sane_get_devices ((const SANE_Device ***)
    &reply.device_list,<br>
                    SANE_TRUE);<br>
    <br>
    to <br>
    <br>
          sane_get_devices ((const SANE_Device ***)
    &reply.device_list,<br>
                    SANE_FALSE);<br>
    <br>
    This removes the restriction on local-only devices.<br>
    <br>
    or:<br>
    <br>
    B. Rebuild the net backend with a small change to the code around
    line 1223 of net.c:<br>
    <br>
      if (local_only)<br>
        {<br>
          *device_list = empty_devlist;<br>
          return SANE_STATUS_GOOD;<br>
        }<br>
    <br>
    ...by removing this code entirely.<br>
    <br>
    If you are willing to give this a try, I would say that changing the
    net backend and using that is probably the easiest solution.<br>
    To give it a go, I would clone the backends repo, make the change,
    build it, take the built net backend files (libsane-net.*) and
    temporarily replace your regular ones on Server B with the built
    ones so that Server B's saned will see them.<br>
    Probably not a good permanent solution but a place to start at
    least.<br>
    <br>
    Actually, since we have had this question come up a couple of times
    in the past, it might be an optional feature that we could add,
    switched off by default, to the core code.<br>
    <br>
    Anyway, let us know if you need help giving that a try.<br>
    <br>
    Cheers,<br>
    Ralph<br>
  </div>

</blockquote></div>