- added "netbios name" option in smb.conf to make controlling the name
authorAndrew Tridgell <tridge@samba.org>
Mon, 19 Aug 1996 11:17:29 +0000 (11:17 +0000)
committerAndrew Tridgell <tridge@samba.org>
Mon, 19 Aug 1996 11:17:29 +0000 (11:17 +0000)
that samba uses possible

- added "socket address" option to allow virtual SMB servers (on
systems with IP aliasing line Linux)

- disabled FAST_SHARE_MODES by default in Linux as older Linux boxes
can't do shared writeable mappings. We really need autoconf ...

- added new option types in loadparm so a string type can be specified
ot be uppercase only, this is used for the workgroup and netbios name
options

- auto-create the lock directory if it doesn't exist in shared mem
startup

- get rid of announce_backup()

- change a few comments in nmbd code

- rewrote the chaining code completely. Hopefully it will handle any
depth chains now.

- added LPRng support

20 files changed:
source/client/client.c
source/client/clientutil.c
source/include/includes.h
source/include/proto.h
source/include/smb.h
source/lib/system.c
source/lib/util.c
source/locking/locking.c
source/nameannounce.c
source/nameannounce.doc
source/nameelect.c
source/namepacket.c
source/namework.c
source/nmbd/nmbd.c
source/param/loadparm.c
source/printing/printing.c
source/smbd/pipes.c
source/smbd/reply.c
source/smbd/server.c
source/utils/nmblookup.c

index b0e4f4a0044fe291ef53d780b3486b5c85a78bad..6bd94be7569007e638990d50842fd9c6718e8a35 100644 (file)
@@ -33,7 +33,7 @@ pstring cur_dir = "\\";
 pstring cd_path = "";
 pstring service="";
 pstring desthost="";
-pstring myname = "";
+extern pstring myname;
 pstring password = "";
 pstring username="";
 pstring workgroup=WORKGROUP;
@@ -3988,11 +3988,10 @@ static BOOL open_sockets(int port )
       strcpy(desthost,host);
     }
 
-  if (*myname == 0)
-    {
+  if (*myname == 0) {
       get_myname(myname,NULL);
-      strupper(myname);
-    }
+  }
+  strupper(myname);
 
   DEBUG(3,("Opening sockets\n"));
 
@@ -4008,7 +4007,8 @@ static BOOL open_sockets(int port )
        /* Try and resolve the name with the netbios server */
        int             bcast;
 
-       if ((bcast = open_socket_in(SOCK_DGRAM, 0, 3)) != -1) {
+       if ((bcast = open_socket_in(SOCK_DGRAM, 0, 3,
+                                   interpret_addr(lp_socket_address()))) != -1) {
          set_socket_options(bcast, "SO_BROADCAST");
 
          if (name_query(bcast, host, 0x20, True, True, *iface_bcast(dest_ip),
index 41c482196adb692c404764fed31689a8c708ff1c..e684d426121044c9bc0cda762986020a13536029 100644 (file)
@@ -31,7 +31,7 @@
 
 pstring service="";
 pstring desthost="";
-pstring myname = "";
+extern pstring myname;
 pstring password = "";
 pstring username="";
 pstring workgroup=WORKGROUP;
@@ -819,10 +819,8 @@ BOOL cli_open_sockets(int port)
   DEBUG(5,("Opening sockets\n"));
 
   if (*myname == 0)
-    {
-      get_myname(myname,NULL);
-      strupper(myname);
-    }
+    get_myname(myname,NULL);
+  strupper(myname);
 
   if (!have_ip)
     {
index 35ef18055ced7d7f04f9a1a8cdcea622068ec042..c7acbddc2b3d9f80c550fde7f5d30e966dfdf914 100644 (file)
@@ -220,7 +220,6 @@ Here come some platform specific sections
 #define HAVE_BZERO
 #define HAVE_MEMMOVE
 #define USE_SIGPROCMASK
-#define FAST_SHARE_MODES 1
 #if 0
 /* SETFS disabled until we can check on some bug reports */
 #if _LINUX_C_LIB_VERSION_MAJOR >= 5
index c1697dc6416c2b39b71dabd3a937ff6ba73cde78..9ddf7cb1fd89a88ba17ffbfac91f47268c614279 100644 (file)
@@ -143,6 +143,7 @@ char *lp_logon_script(void);
 char *lp_remote_announce(void);
 char *lp_wins_server(void);
 char *lp_interfaces(void);
+char *lp_socket_address(void);
 BOOL lp_wins_support(void);
 BOOL lp_wins_proxy(void);
 BOOL lp_domain_master(void);
@@ -297,7 +298,6 @@ void do_announce_request(char *info, char *to_name, int announce_type,
 void sync_server(enum state_type state, char *serv_name, char *work_name, 
                 int name_type,
                 struct in_addr ip);
-void announce_backup(void);
 void do_announce_host(int command,
                char *from_name, int from_type, struct in_addr from_ip,
                char *to_name  , int to_type  , struct in_addr to_ip,
@@ -305,7 +305,7 @@ void do_announce_host(int command,
                char *server_name, int server_type, char *server_comment);
 void remove_my_servers(void);
 void announce_server(struct subnet_record *d, struct work_record *work,
-                                       char *name, char *comment, time_t ttl, int server_type);
+                    char *name, char *comment, time_t ttl, int server_type);
 void announce_host(void);
 void announce_master(void);
 void announce_remote(void);
@@ -686,7 +686,7 @@ BOOL claim_connection(int cnum,char *name,int max_connections,BOOL Clear);
 void exit_server(char *reason);
 void standard_sub(int cnum,char *s);
 char *smb_fn_name(int type);
-int chain_reply(int type,char *inbuf,char *inbuf2,char *outbuf,char *outbuf2,int size,int bufsize);
+int chain_reply(char *inbuf,char *outbuf,int size,int bufsize);
 int construct_reply(char *inbuf,char *outbuf,int size,int bufsize);
 
 /*The following definitions come from  shmem.c  */
@@ -891,9 +891,9 @@ int byte_checksum(char *buf,int len);
 char *dirname_dos(char *path,char *buf);
 void *Realloc(void *p,int size);
 void Abort(void );
-BOOL get_myname(char *myname,struct in_addr *ip);
+BOOL get_myname(char *my_name,struct in_addr *ip);
 BOOL ip_equal(struct in_addr ip1,struct in_addr ip2);
-int open_socket_in(int type, int port, int dlevel);
+int open_socket_in(int type, int port, int dlevel,uint32 socket_addr);
 int open_socket_out(int type, struct in_addr *addr, int port );
 int interpret_protocol(char *str,int def);
 int interpret_security(char *str,int def);
index c9180dd50ca560b16c77d43148b844069853ea15..349d406b49f7c7361029c327fa096ffcc2dd3423 100644 (file)
@@ -796,7 +796,7 @@ enum security_types {SEC_SHARE,SEC_USER,SEC_SERVER};
 
 /* printing types */
 enum printing_types {PRINT_BSD,PRINT_SYSV,PRINT_AIX,PRINT_HPUX,
-                    PRINT_QNX,PRINT_PLP};
+                    PRINT_QNX,PRINT_PLP,PRINT_LPRNG};
 
 
 /* case handling */
index 1410b776ab13cbbb43f43aad2e0d75dc06bf622e..81e9a6679ad19a4a449f8d37f65212c879439313 100644 (file)
@@ -98,7 +98,7 @@ int sys_select(fd_set *fds,struct timeval *tval)
   do {
     if (tval) memcpy((void *)&t2,(void *)tval,sizeof(t2));
     errno = 0;
-    selrtn = select(16,SELECT_CAST fds,NULL,NULL,tval?&t2:NULL);
+    selrtn = select(255,SELECT_CAST fds,NULL,NULL,tval?&t2:NULL);
   } while (selrtn<0 && errno == EINTR);
 
   return(selrtn);
index 5ef1d21a7aabe27da5836a198f505412abb19516..2f3ac1bb150685c306f53bd6b6dc8ddd47444bbc 100644 (file)
@@ -48,6 +48,9 @@ struct in_addr lastip;
 /* the last port received from */
 int lastport=0;
 
+/* this is used by the chaining code */
+int chain_size = 0;
+
 int trans_num = 0;
 
 /*
@@ -73,7 +76,7 @@ fstring remote_proto="UNKNOWN";
 pstring myhostname="";
 pstring user_socket_options="";   
 pstring sesssetup_user="";
-
+pstring myname = "";
 
 int smb_read_error = 0;
 
@@ -1075,7 +1078,7 @@ return the SMB offset into an SMB buffer
 ********************************************************************/
 int smb_offset(char *p,char *buf)
 {
-  return(PTR_DIFF(p,buf+4));
+  return(PTR_DIFF(p,buf+4) + chain_size);
 }
 
 
@@ -2696,7 +2699,7 @@ void Abort(void )
 /****************************************************************************
 get my own name and IP
 ****************************************************************************/
-BOOL get_myname(char *myname,struct in_addr *ip)
+BOOL get_myname(char *my_name,struct in_addr *ip)
 {
   struct hostent *hp;
   pstring hostname;
@@ -2717,13 +2720,13 @@ BOOL get_myname(char *myname,struct in_addr *ip)
       return False;
     }
 
-  if (myname)
+  if (my_name)
     {
       /* split off any parts after an initial . */
       char *p = strchr(hostname,'.');
       if (p) *p = 0;
 
-      strcpy(myname,hostname);
+      strcpy(my_name,hostname);
     }
 
   if (ip)
@@ -2748,7 +2751,7 @@ BOOL ip_equal(struct in_addr ip1,struct in_addr ip2)
 /****************************************************************************
 open a socket of the specified type, port and address for incoming data
 ****************************************************************************/
-int open_socket_in(int type, int port, int dlevel)
+int open_socket_in(int type, int port, int dlevel,uint32 socket_addr)
 {
   struct hostent *hp;
   struct sockaddr_in sock;
@@ -2773,7 +2776,7 @@ int open_socket_in(int type, int port, int dlevel)
 #endif
   sock.sin_port = htons( port );
   sock.sin_family = hp->h_addrtype;
-  sock.sin_addr.s_addr = INADDR_ANY;
+  sock.sin_addr.s_addr = socket_addr;
   res = socket(hp->h_addrtype, type, 0);
   if (res == -1) 
     { DEBUG(0,("socket failed\n")); return -1; }
@@ -2788,15 +2791,15 @@ int open_socket_in(int type, int port, int dlevel)
     { 
       if (port) {
        if (port == SMB_PORT || port == NMB_PORT)
-         DEBUG(dlevel,("bind failed on port %d (%s)\n",
-                       port,strerror(errno))); 
+         DEBUG(dlevel,("bind failed on port %d socket_addr=%x (%s)\n",
+                       port,socket_addr,strerror(errno))); 
        close(res); 
 
        if (dlevel > 0 && port < 1000)
          port = 7999;
 
        if (port >= 1000 && port < 9000)
-         return(open_socket_in(type,port+1,dlevel));
+         return(open_socket_in(type,port+1,dlevel,socket_addr));
       }
 
       return(-1); 
index 966bb2253b7e971dcd2d000bfd2e5e39a035bb94..04f4a4b1975a859376f313ae1ab5381342bbd41d 100644 (file)
@@ -240,6 +240,8 @@ BOOL start_share_mode_mgmt(void)
    pstring shmem_file_name;
    
   strcpy(shmem_file_name,lp_lockdir());
+  if (!directory_exist(shmem_file_name,NULL))
+    mkdir(shmem_file_name,0755);
   trim_string(shmem_file_name,"","/");
   if (!*shmem_file_name) return(False);
   strcat(shmem_file_name, "/SHARE_MEM_FILE");
index 0127ae03e37586ea950bf80732e3b3d6879e9da4..09aade86efa072aa425041ac0644e1ae2bcc7a34 100644 (file)
@@ -136,102 +136,6 @@ void sync_server(enum state_type state, char *serv_name, char *work_name,
 }
 
 
-/****************************************************************************
-  construct a host announcement unicast
-
-  this function should not be used heavily, and only when we are _not_
-  a master browser and _not_ a primary domain controller.
-
-  **************************************************************************/
-void announce_backup(void)
-{
-  static time_t lastrun = 0;
-  time_t t = time(NULL);
-  pstring outbuf;
-  char *p;
-  struct subnet_record *d1;
-  int tok;
-  static uint32 id_count = 0;
-  
-  if (!lastrun) lastrun = t;
-#if 1
-  if (t < lastrun + 1 * 60)
-#else
-  if (t < lastrun + CHECK_TIME_ANNOUNCE_BACKUP * 60)
-#endif
-       return;
-  lastrun = t;
-  
-  DEBUG(4,("checking backups...\n"));
-
-  for (tok = 0; tok <= workgroup_count; tok++)
-    {
-      for (d1 = subnetlist; d1; d1 = d1->next)
-       {
-         struct work_record *work;
-         struct subnet_record *d;
-         
-         /* search for unique workgroup: only the name matters */
-         for (work = d1->workgrouplist;
-              work && (tok != work->token);
-              work = work->next);
-         
-         if (!work) continue;
-
-      if (AM_MASTER(work) && AM_DOMCTL(work)) continue;
-
-         /* found one: announce it across all domains */
-         for (d = subnetlist; d; d = d->next)
-           {
-             
-             DEBUG(2,("sending announce backup %s workgroup %s(%d)\n",
-                      inet_ntoa(d->bcast_ip),work->work_group,
-                      work->token));
-             
-             bzero(outbuf,sizeof(outbuf));
-             p = outbuf;
-
-             CVAL(p,0) = ANN_GetBackupListReq;
-             CVAL(p,1) = work->token; /* workgroup unique key index */
-             SIVAL(p,2,++id_count); /* unique count. not that we use it! */
-
-             p += 6;
-             
-          debug_browse_data(outbuf, PTR_DIFF(p,outbuf));
-
-             if (!AM_DOMCTL(work))
-          {
-            /* only ask for a list of backup domain controllers
-               if we are not a domain controller ourselves */
-                       
-               send_mailslot_reply(BROWSE_MAILSLOT,
-                                 ClientDGRAM,outbuf,
-                                 PTR_DIFF(p,outbuf),
-                                 myname, work->work_group,
-                                 0x0,0x1b,d->bcast_ip,
-                                 *iface_ip(d->bcast_ip));
-          }
-
-          debug_browse_data(outbuf, PTR_DIFF(p,outbuf));
-
-             if (!AM_MASTER(work))
-          {
-            /* only ask for a list of master browsers if we
-               are not a master browser ourselves */
-
-               send_mailslot_reply(BROWSE_MAILSLOT,
-                                 ClientDGRAM,outbuf,
-                                 PTR_DIFF(p,outbuf),
-                                 myname, work->work_group,
-                                 0x0,0x1d,d->bcast_ip,
-                                 *iface_ip(d->bcast_ip));
-          }
-           }
-       }
-    }
-}
-
-
 /****************************************************************************
   send a host announcement packet
   **************************************************************************/
@@ -305,7 +209,7 @@ void remove_my_servers(void)
   announce a server entry
   ****************************************************************************/
 void announce_server(struct subnet_record *d, struct work_record *work,
-                                       char *name, char *comment, time_t ttl, int server_type)
+                    char *name, char *comment, time_t ttl, int server_type)
 {
        uint32 domain_type = SV_TYPE_DOMAIN_ENUM|SV_TYPE_SERVER_UNIX;
        BOOL wins_iface = ip_equal(d->bcast_ip, ipgrp);
@@ -315,7 +219,8 @@ void announce_server(struct subnet_record *d, struct work_record *work,
                /* wins pseudo-ip interface */
                if (!AM_MASTER(work))
                {
-                       /* non-master announce by unicast to the domain master */
+                       /* non-master announce by unicast to the domain 
+                          master */
                        if (!lp_wins_support() && *lp_wins_server())
                        {
                                /* look up the domain master with the WINS server */
@@ -441,14 +346,6 @@ void announce_host(void)
          
          work->lastannounce_time = t;
 
-         /*
-         if (!d->my_interface) {
-           stype &= ~(SV_TYPE_POTENTIAL_BROWSER | SV_TYPE_MASTER_BROWSER |
-                      SV_TYPE_DOMAIN_MASTER | SV_TYPE_BACKUP_BROWSER |
-                      SV_TYPE_DOMAIN_CTRL | SV_TYPE_DOMAIN_MEMBER);
-         }
-         */
-
          for (s = work->serverlist; s; s = s->next) {
            if (strequal(myname, s->serv.name)) { 
              announce = True; 
@@ -456,9 +353,9 @@ void announce_host(void)
            }
          }
          
-         if (announce)
-         {
-               announce_server(d,work,my_name,comment,work->announce_interval,stype);
+         if (announce) {
+           announce_server(d,work,my_name,comment,
+                           work->announce_interval,stype);
          }
          
          if (work->needannounce)
index a1e33cb8008c7f72620a98d1dabbc1f04e25259c..e04a59209a1f42d60b978b1884ddf976ec18754f 100644 (file)
@@ -81,7 +81,7 @@ via name queries will just lead to lag and propogation delays, because
 if two parts of the net choose different DMBs then the data will be
 very slow to propoogate.
 
-If a DMB is configured then just sent the master announcemnt to that
+If a DMB is configured then just send the master announcemnt to that
 box! Thats all that needs to be done. Just send a udp 138 packet and
 forget it. If the recipient is indeed a DMB (as it should be if the
 config file is correct) then it should initiate a browse list sync
index 38b4d5d80e741e5541fec73e5b496bf7b8a51ab9..2edc484ba0c2263bd80589efdb282e6aadea6756 100644 (file)
@@ -502,7 +502,7 @@ void run_elections(void)
                           work->work_group,inet_ntoa(d->bcast_ip)));
                  
                  work->RunningElection = False;
-          work->state = MST_NONE;
+                 work->state = MST_NONE;
 
                  become_master(d, work);
                }
index a752ef5dfaecc6010bba8c919fde616cc5937ce2..4be5a959526c513a4393002816fff8781cfb36d0 100644 (file)
@@ -360,7 +360,8 @@ static void process_nmb(struct packet_struct *p)
     {
        if (nmb->header.qdcount==0 || nmb->header.arcount==0) break;
        if (nmb->header.response)
-         response_netbios_packet(p); /* response to registration dealt with here */
+         response_netbios_packet(p); /* response to registration dealt 
+                                        with here */
        else
          reply_name_reg(p);
        break;
@@ -409,7 +410,8 @@ static void process_nmb(struct packet_struct *p)
          }
        
        if (nmb->header.response)
-         response_netbios_packet(p); /* response to reply dealt with in here */
+         response_netbios_packet(p); /* response to reply dealt with 
+                                        in here */
        else
          reply_name_release(p);
       break;
@@ -457,10 +459,11 @@ void listen_for_packets(BOOL run_election)
   FD_SET(ClientNMB,&fds);
   FD_SET(ClientDGRAM,&fds);
 
-  /* during elections and when expecting a netbios response packet we need
-     to send election packets at one second intervals.
-     XXXX actually, it needs to be the interval (in ms) between time now and the
-     time we are expecting the next netbios packet */
+  /* during elections and when expecting a netbios response packet we
+     need to send election packets at tighter intervals 
+
+     ideally it needs to be the interval (in ms) between time now and
+     the time we are expecting the next netbios packet */
 
   timeout.tv_sec = (run_election||num_response_packets) ? 1 : NMBD_SELECT_LOOP;
   timeout.tv_usec = 0;
@@ -471,17 +474,14 @@ void listen_for_packets(BOOL run_election)
     {
       struct packet_struct *packet = read_packet(ClientNMB, NMB_PACKET);
       if (packet) {
-#if 1
        if (ismyip(packet->ip) &&
            (packet->port == NMB_PORT || packet->port == DGRAM_PORT)) {
-         DEBUG(5,("discarding own packet from %s:%d\n",
+         DEBUG(7,("discarding own packet from %s:%d\n",
                   inet_ntoa(packet->ip),packet->port));          
          free_packet(packet);
-       } else 
-#endif
-         {
-           queue_packet(packet);
-         }
+       } else {
+         queue_packet(packet);
+       }
       }
     }
 
@@ -489,17 +489,14 @@ void listen_for_packets(BOOL run_election)
     {
       struct packet_struct *packet = read_packet(ClientDGRAM, DGRAM_PACKET);
       if (packet) {
-#if 1
        if (ismyip(packet->ip) &&
              (packet->port == NMB_PORT || packet->port == DGRAM_PORT)) {
-         DEBUG(5,("discarding own packet from %s:%d\n",
+         DEBUG(7,("discarding own packet from %s:%d\n",
                   inet_ntoa(packet->ip),packet->port));          
          free_packet(packet);
-       } else
-#endif 
-         {
-           queue_packet(packet);
-         }
+       } else {
+         queue_packet(packet);
+       }
       }
     }
 }
index 74c567fa748116c342072c4fe47c07d94f3e078e..108048d5001de7d011ef28f0286c42662085aefe 100644 (file)
@@ -284,11 +284,12 @@ static void process_announce(struct packet_struct *p,uint16 command,char *buf)
   tell_become_backup();
 #endif
 
-  /* get the local_only browse list from the local master and add it to ours. */
+  /* get the local_only browse list from the local master and add it 
+     to ours. */
   if (command == ANN_LocalMasterAnnouncement)
   {
     add_browser_entry(serv_name,dgram->dest_name.name_type,
-                   work->work_group,30,ip,True);
+                     work->work_group,30,ip,True);
   }
 }
 
index 82ea9550f30b1ad5860c595f5e4e50e1298c681c..2621be87ee544ae7fa2a38b5b092d460dd20d50e 100644 (file)
@@ -305,14 +305,6 @@ static void process(void)
 
       announce_host();
 
-#if 0
-      /* XXXX what was this stuff supposed to do? It sent
-        ANN_GetBackupListReq packets which I think should only be
-        sent when trying to find out who to browse with */      
-
-      announce_backup();
-#endif
-
       announce_master();
 
       announce_remote();
@@ -344,11 +336,11 @@ static BOOL open_sockets(BOOL isdaemon, int port)
   }   
 
   if (isdaemon)
-    ClientNMB = open_socket_in(SOCK_DGRAM, port,0);
+    ClientNMB = open_socket_in(SOCK_DGRAM, port,0,interpret_addr(lp_socket_address()));
   else
     ClientNMB = 0;
   
-  ClientDGRAM = open_socket_in(SOCK_DGRAM,DGRAM_PORT,3);
+  ClientDGRAM = open_socket_in(SOCK_DGRAM,DGRAM_PORT,3,interpret_addr(lp_socket_address()));
 
   if (ClientNMB == -1)
     return(False);
@@ -376,8 +368,8 @@ static BOOL init_structs()
     strcpy(myname,myhostname);
     p = strchr(myname,'.');
     if (p) *p = 0;
-    strupper(myname);
   }
+  strupper(myname);
 
   return True;
 }
@@ -490,11 +482,11 @@ static void usage(char *pname)
   DEBUG(1,("%s netbios nameserver version %s started\n",timestring(),VERSION));
   DEBUG(1,("Copyright Andrew Tridgell 1994\n"));
 
-  init_structs();
-
   if (!reload_services(False))
     return(-1);        
 
+  init_structs();
+
   set_samba_nb_type();
 
   if (!is_daemon && !is_a_socket(0)) {
index 953613fd747a636dfec0eb8bd70a4686db5cc9bc..87209d1bb7c21fbac77c48fcefac695dac574e82 100644 (file)
@@ -53,6 +53,7 @@ BOOL bLoaded = False;
 
 extern int DEBUGLEVEL;
 extern pstring user_socket_options;
+extern pstring myname;
 
 #ifndef GLOBAL_NAME
 #define GLOBAL_NAME "global"
@@ -83,7 +84,8 @@ extern pstring user_socket_options;
 /* these are the types of parameter we have */
 typedef enum
 {
-  P_BOOL,P_BOOLREV,P_CHAR,P_INTEGER,P_OCTAL,P_STRING,P_GSTRING
+  P_BOOL,P_BOOLREV,P_CHAR,P_INTEGER,P_OCTAL,
+  P_STRING,P_USTRING,P_GSTRING,P_UGSTRING
 } parm_type;
 
 typedef enum
@@ -130,6 +132,7 @@ typedef struct
   char *szWINSserver;
   char *szInterfaces;
   char *szRemoteAnnounce;
+  char *szSocketAddress;
   int max_log_size;
   int mangled_stack;
   int max_xmit;
@@ -371,6 +374,7 @@ struct parm_struct
   {"interfaces",       P_STRING,  P_GLOBAL, &Globals.szInterfaces,      NULL},
   {"password server",  P_STRING,  P_GLOBAL, &Globals.szPasswordServer,  NULL},
   {"socket options",   P_GSTRING, P_GLOBAL, user_socket_options,        NULL},
+  {"netbios name",     P_UGSTRING,P_GLOBAL, myname,                     NULL},
   {"smbrun",           P_STRING,  P_GLOBAL, &Globals.szSmbrun,          NULL},
   {"log file",         P_STRING,  P_GLOBAL, &Globals.szLogFile,         NULL},
   {"config file",      P_STRING,  P_GLOBAL, &Globals.szConfigFile,      NULL},
@@ -393,12 +397,13 @@ struct parm_struct
   {"passwd program",   P_STRING,  P_GLOBAL, &Globals.szPasswdProgram,   NULL},
   {"passwd chat",      P_STRING,  P_GLOBAL, &Globals.szPasswdChat,      NULL},
   {"valid chars",      P_STRING,  P_GLOBAL, &Globals.szValidChars,      handle_valid_chars},
-  {"workgroup",        P_STRING,  P_GLOBAL, &Globals.szWorkGroup,       NULL},
+  {"workgroup",        P_USTRING, P_GLOBAL, &Globals.szWorkGroup,       NULL},
   {"domain controller",P_STRING,  P_GLOBAL, &Globals.szDomainController,NULL},
   {"username map",     P_STRING,  P_GLOBAL, &Globals.szUsernameMap,     NULL},
   {"character set",    P_STRING,  P_GLOBAL, &Globals.szCharacterSet,    handle_character_set},
   {"logon script",     P_STRING,  P_GLOBAL, &Globals.szLogonScript,     NULL},
   {"remote announce",  P_STRING,  P_GLOBAL, &Globals.szRemoteAnnounce,  NULL},
+  {"socket address",   P_STRING,  P_GLOBAL, &Globals.szSocketAddress,   NULL},
   {"max log size",     P_INTEGER, P_GLOBAL, &Globals.max_log_size,      NULL},
   {"mangled stack",    P_INTEGER, P_GLOBAL, &Globals.mangled_stack,     NULL},
   {"max mux",          P_INTEGER, P_GLOBAL, &Globals.max_mux,           NULL},
@@ -525,7 +530,8 @@ static void init_globals(void)
       bzero((void *)&Globals,sizeof(Globals));
 
       for (i = 0; parm_table[i].label; i++) 
-       if (parm_table[i].type == P_STRING && 
+       if ((parm_table[i].type == P_STRING ||
+            parm_table[i].type == P_USTRING) && 
            parm_table[i].ptr)
          string_init(parm_table[i].ptr,"");
 
@@ -551,6 +557,7 @@ static void init_globals(void)
   string_set(&Globals.szLockDir, LOCKDIR);
   string_set(&Globals.szRootdir, "/");
   string_set(&Globals.szSmbrun, SMBRUN);
+  string_set(&Globals.szSocketAddress, "0.0.0.0");
   sprintf(s,"Samba %s",VERSION);
   string_set(&Globals.szServerString,s);
   Globals.bLoadPrinters = True;
@@ -611,6 +618,7 @@ static void init_locals(void)
     {
     case PRINT_BSD:
     case PRINT_AIX:
+    case PRINT_LPRNG:
     case PRINT_PLP:
       string_initial(&sDefault.szLpqcommand,"lpq -P%p");
       string_initial(&sDefault.szLprmcommand,"lprm -P%p %j");
@@ -735,6 +743,7 @@ FN_GLOBAL_STRING(lp_logon_script,&Globals.szLogonScript)
 FN_GLOBAL_STRING(lp_remote_announce,&Globals.szRemoteAnnounce) 
 FN_GLOBAL_STRING(lp_wins_server,&Globals.szWINSserver)
 FN_GLOBAL_STRING(lp_interfaces,&Globals.szInterfaces)
+FN_GLOBAL_STRING(lp_socket_address,&Globals.szSocketAddress)
 
 FN_GLOBAL_BOOL(lp_wins_support,&Globals.bWINSsupport)
 FN_GLOBAL_BOOL(lp_wins_proxy,&Globals.bWINSproxy)
@@ -875,7 +884,9 @@ static void free_service(service *pservice)
      return;
 
   for (i=0;parm_table[i].label;i++)
-    if (parm_table[i].type == P_STRING && parm_table[i].class == P_LOCAL)
+    if ((parm_table[i].type == P_STRING ||
+        parm_table[i].type == P_STRING) &&
+       parm_table[i].class == P_LOCAL)
       string_free((char **)(((char *)pservice) + PTR_DIFF(parm_table[i].ptr,&sDefault)));
 }
 
@@ -1164,6 +1175,11 @@ static void copy_service(service *pserviceDest,
          case P_STRING:
            string_set(dest_ptr,*(char **)src_ptr);
            break;
+
+         case P_USTRING:
+           string_set(dest_ptr,*(char **)src_ptr);
+           strupper(*(char **)dest_ptr);
+           break;
          default:
            break;
          }
@@ -1344,6 +1360,8 @@ static BOOL handle_printing(char *pszParmValue,int *val)
     *val = PRINT_QNX;
   else if (strequal(pszParmValue,"plp"))
     *val = PRINT_PLP;
+  else if (strequal(pszParmValue,"lprng"))
+    *val = PRINT_LPRNG;
   return(True);
 }
 
@@ -1526,9 +1544,19 @@ static BOOL do_parameter(char *pszParmName, char *pszParmValue)
        string_set(parm_ptr,pszParmValue);
        break;
 
+     case P_USTRING:
+       string_set(parm_ptr,pszParmValue);
+       strupper(*(char **)parm_ptr);
+       break;
+
      case P_GSTRING:
        strcpy((char *)parm_ptr,pszParmValue);
        break;
+
+     case P_UGSTRING:
+       strcpy((char *)parm_ptr,pszParmValue);
+       strupper((char *)parm_ptr);
+       break;
      }
 
    return(True);
@@ -1562,11 +1590,13 @@ static void print_parameter(parm_type type,void *ptr)
       break;
       
     case P_GSTRING:
+    case P_UGSTRING:
       if ((char *)ptr)
        printf("%s",(char *)ptr);
       break;
 
     case P_STRING:
+    case P_USTRING:
       if (*(char **)ptr)
        printf("%s",*(char **)ptr);
       break;
@@ -1593,6 +1623,7 @@ static BOOL equal_parameter(parm_type type,void *ptr1,void *ptr2)
       return(*((char *)ptr1) == *((char *)ptr2));
 
     case P_GSTRING:
+    case P_UGSTRING:
       {
        char *p1 = (char *)ptr1, *p2 = (char *)ptr2;
        if (p1 && !*p1) p1 = NULL;
@@ -1600,6 +1631,7 @@ static BOOL equal_parameter(parm_type type,void *ptr1,void *ptr2)
        return(p1==p2 || strequal(p1,p2));
       }
     case P_STRING:
+    case P_USTRING:
       {
        char *p1 = *(char **)ptr1, *p2 = *(char **)ptr2;
        if (p1 && !*p1) p1 = NULL;
index 00df859e0ab752dff144cdff67e04facd525d170..d1b702cb0a432eddeebddd8cb227786be223257a 100644 (file)
@@ -277,6 +277,157 @@ static BOOL parse_lpq_bsd(char *line,print_queue_struct *buf,BOOL first)
   return(True);
 }
 
+/*
+<magnus@hum.auc.dk>
+LPRng_time modifies the current date by inserting the hour and minute from
+the lpq output.  The lpq time looks like "23:15:07"
+*/
+static time_t LPRng_time(string tok[],int pos)
+{
+  time_t jobtime;
+  struct tm *t;
+  char tmp_time[9];
+
+  jobtime = time(NULL);         /* default case: take current time */
+  t = localtime(&jobtime);
+  t->tm_hour = atoi(tok[pos]);
+  StrnCpy(tmp_time,tok[pos],sizeof(tmp_time));
+  t->tm_min = atoi(tmp_time+3);
+  t->tm_sec = atoi(tmp_time+6);
+  jobtime = mktime(t);
+
+  return jobtime;
+}
+
+
+/****************************************************************************
+  parse a lpq line
+  <magnus@hum.auc.dk>
+  Most of the code is directly reused from parse_lpq_bsd()
+
+here are two examples of lpq output under lprng (LPRng-2.3.0)
+
+Printer: humprn@hum-fak
+  Queue: 1 printable job
+  Server: pid 4840 active, Unspooler: pid 4841 active
+  Status: job 'cfA659hum-fak', closing device at Fri Jun 21 10:10:21 1996
+ Rank  Owner           Class Job Files                           Size Time
+active magnus@hum-fak      A 659 /var/spool/smb/Notesblok-ikke-na4024 10:03:31
+Printer: humprn@hum-fak (printing disabled)
+  Queue: 1 printable job
+  Warning: no server present
+  Status: finished operations at Fri Jun 21 10:10:32 1996
+ Rank  Owner           Class Job Files                           Size Time
+1      magnus@hum-fak      A 387 /var/spool/smb/netbudget.xls    21230 10:50:53
+****************************************************************************/
+static BOOL parse_lpq_lprng(char *line,print_queue_struct *buf,BOOL first)
+{
+#define        LPRNG_RANKTOK   0
+#define        LPRNG_USERTOK 1
+#define        LPRNG_PRIOTOK 2
+#define        LPRNG_JOBTOK    3
+#define        LPRNG_FILETOK   4
+#define        LPRNG_TOTALTOK 5
+#define LPRNG_TIMETOK 6
+#define        LPRNG_NTOK      7
+
+/****************************************************************************
+From lpd_status.c in LPRng source.
+0        1         2         3         4         5         6         7
+12345678901234567890123456789012345678901234567890123456789012345678901234 
+" Rank  Owner           Class Job Files                           Size Time"
+                        plp_snprintf( msg, sizeof(msg), "%-6s %-19s %c %03d %-32s",
+                                number, line, priority, cfp->number, error );
+                                plp_snprintf( msg + len, sizeof(msg)-len, "%4d",
+                                        cfp->jobsize );
+                                plp_snprintf( msg+len, sizeof(msg)-len, " %s",
+                                        Time_str( 1, cfp->statb.st_ctime ) );
+****************************************************************************/
+  /* The following define's are to be able to adjust the values if the
+LPRng source changes.  This is from version 2.3.0.  Magnus  */
+#define SPACE_W 1
+#define RANK_W 6
+#define OWNER_W 19
+#define CLASS_W 1
+#define JOB_W 3
+#define FILE_W 32
+/* The JOBSIZE_W is too small for big jobs, so time is pushed to the right */
+#define JOBSIZE_W 4
+#define RANK_POS 0
+#define OWNER_POS RANK_POS+RANK_W+SPACE_W
+#define CLASS_POS OWNER_POS+OWNER_W+SPACE_W
+#define JOB_POS CLASS_POS+CLASS_W+SPACE_W
+#define FILE_POS JOB_POS+JOB_W+SPACE_W
+#define JOBSIZE_POS FILE_POS+FILE_W
+
+  
+  string tok[LPRNG_NTOK];
+  int count=0;
+
+/* 
+Need to insert one space in front of the size, to be able to use
+next_token() unchanged.  I would have liked to be able to insert a
+space instead, to prevent losing that one char, but perl has spoiled
+me :-\  So I did it the easiest way.
+
+HINT: Use as short a path as possible for the samba spool directory.
+A long spool-path will just waste significant chars of the file name.
+*/
+
+  (char)line[JOBSIZE_POS-1]=' ';
+
+  /* handle the case of "(stdin)" as a filename */
+  string_sub(line,"stdin","STDIN");
+  string_sub(line,"(","\"");
+  string_sub(line,")","\"");
+  
+  for (count=0; count<LPRNG_NTOK && next_token(&line,tok[count],NULL); count++) ;
+
+  /* we must get LPRNG_NTOK tokens */
+  if (count < LPRNG_NTOK)
+    return(False);
+
+  /* the Job and Total columns must be integer */
+  if (!isdigit(*tok[LPRNG_JOBTOK]) || !isdigit(*tok[LPRNG_TOTALTOK])) return(False);
+
+  /* if the fname contains a space then use STDIN */
+  /* I do not understand how this would be possible. Magnus. */
+  if (strchr(tok[LPRNG_FILETOK],' '))
+    strcpy(tok[LPRNG_FILETOK],"STDIN");
+
+  /* only take the last part of the filename */
+  {
+    string tmp;
+    char *p = strrchr(tok[LPRNG_FILETOK],'/');
+    if (p)
+      {
+       strcpy(tmp,p+1);
+       strcpy(tok[LPRNG_FILETOK],tmp);
+      }
+  }
+       
+
+  buf->job = atoi(tok[LPRNG_JOBTOK]);
+  buf->size = atoi(tok[LPRNG_TOTALTOK]);
+  buf->status = strequal(tok[LPRNG_RANKTOK],"active")?LPQ_PRINTING:LPQ_QUEUED;
+  /*  buf->time = time(NULL); */
+  buf->time = LPRng_time(tok,LPRNG_TIMETOK);
+DEBUG(3,("Time reported for job %d is %s", buf->job, ctime(&buf->time)));
+  StrnCpy(buf->user,tok[LPRNG_USERTOK],sizeof(buf->user)-1);
+  StrnCpy(buf->file,tok[LPRNG_FILETOK],sizeof(buf->file)-1);
+#ifdef LPRNG_PRIOTOK
+  /* Here I try to map the CLASS char to a number, but the number
+     is never shown in Print Manager under NT anyway... Magnus. */
+  buf->priority = atoi(tok[LPRNG_PRIOTOK-('A'-1)]);
+#else
+  buf->priority = 1;
+#endif
+  return(True);
+}
+
 
 
 /*******************************************************************
@@ -695,6 +846,9 @@ static BOOL parse_lpq_entry(int snum,char *line,
     case PRINT_QNX:
       ret = parse_lpq_qnx(line,buf,first);
       break;
+    case PRINT_LPRNG:
+      ret = parse_lpq_lprng(line,buf,first);
+      break;
     case PRINT_PLP:
       ret = parse_lpq_plp(line,buf,first);
       break;
index 724f58e1e2716a29658b4d341a92126e6acf8790..ffa46083c3d89947b5026c1a66223a3484d30170 100644 (file)
@@ -35,7 +35,6 @@
 /* look in server.c for some explanation of these variables */
 extern int Protocol;
 extern int DEBUGLEVEL;
-extern int chain_size;
 extern int maxxmit;
 extern int chain_fnum;
 extern char magic_char;
@@ -72,9 +71,6 @@ int reply_open_pipe_and_X(char *inbuf,char *outbuf,int length,int bufsize)
   pstring fname;
   int cnum = SVAL(inbuf,smb_tid);
   int fnum = -1;
-  int outsize = 0;
-  int smb_com2 = CVAL(inbuf,smb_vwv0);
-  int smb_off2 = SVAL(inbuf,smb_vwv1);
   int smb_mode = SVAL(inbuf,smb_vwv3);
   int smb_attr = SVAL(inbuf,smb_vwv5);
 #if 0
@@ -149,8 +145,7 @@ int reply_open_pipe_and_X(char *inbuf,char *outbuf,int length,int bufsize)
   }
 
   /* Prepare the reply */
-  outsize = set_message(outbuf,15,0,True);
-  CVAL(outbuf,smb_vwv0) = smb_com2;
+  set_message(outbuf,15,0,True);
 
   /* Put things back the way they were. */
   Connections[cnum].read_only = 1;
@@ -164,7 +159,6 @@ int reply_open_pipe_and_X(char *inbuf,char *outbuf,int length,int bufsize)
     rmode = 1;
   }
 
-  SSVAL(outbuf,smb_vwv1,(chain_size+outsize)-4);
   SSVAL(outbuf,smb_vwv2,fnum);
   SSVAL(outbuf,smb_vwv3,fmode);
   put_dos_date3(outbuf,smb_vwv4,mtime);
@@ -174,17 +168,10 @@ int reply_open_pipe_and_X(char *inbuf,char *outbuf,int length,int bufsize)
 
   chain_fnum = fnum;
 
-  if (smb_com2 != 0xFF)
-    outsize += chain_reply(smb_com2,inbuf,inbuf+smb_off2+4,
-                          outbuf,outbuf+outsize,
-                          length,bufsize);
-
-  chain_fnum = -1;
-
   DEBUG(4,("Opened pipe %s with handle %d, saved name %s.\n",
           fname, fnum, Files[fnum].name));
   
-  return(outsize);
+  return chain_reply(inbuf,outbuf,length,bufsize);
 }
 
 
index 3c2e91d5f5c87bfa676010cceb254148c702e658..a84a9af0c17c7d768c7d0b05c087a85b9d56f1a4 100644 (file)
@@ -30,7 +30,6 @@
 /* look in server.c for some explanation of these variables */
 extern int Protocol;
 extern int DEBUGLEVEL;
-extern int chain_size;
 extern int maxxmit;
 extern int chain_fnum;
 extern char magic_char;
@@ -178,11 +177,8 @@ int reply_tcon_and_X(char *inbuf,char *outbuf,int length,int bufsize)
   pstring password;
   pstring devicename;
   int connection_num;
-  int outsize = 0;
   int uid = SVAL(inbuf,smb_uid);
   int vuid;
-  int smb_com2 = SVAL(inbuf,smb_vwv0);
-  int smb_off2 = SVAL(inbuf,smb_vwv1);
   int passlen = SVAL(inbuf,smb_vwv3);
 
   *service = *user = *password = *devicename = 0;
@@ -221,7 +217,7 @@ int reply_tcon_and_X(char *inbuf,char *outbuf,int length,int bufsize)
   if (connection_num < 0)
     return(connection_error(inbuf,outbuf,connection_num));
 
-  outsize = set_message(outbuf,2,strlen(devicename)+1,True);
+  set_message(outbuf,2,strlen(devicename)+1,True);
   
   DEBUG(3,("%s tconX service=%s user=%s cnum=%d\n",timestring(),service,user,connection_num));
   
@@ -229,17 +225,9 @@ int reply_tcon_and_X(char *inbuf,char *outbuf,int length,int bufsize)
   SSVAL(inbuf,smb_tid,connection_num);
   SSVAL(outbuf,smb_tid,connection_num);
 
-  CVAL(outbuf,smb_vwv0) = smb_com2;
-  SSVAL(outbuf,smb_vwv1,(chain_size + outsize)-4);
-
   strcpy(smb_buf(outbuf),devicename);
 
-  if (smb_com2 != 0xFF)
-    outsize += chain_reply(smb_com2,inbuf,inbuf+smb_off2+4,
-                          outbuf,outbuf+outsize,
-                          length,bufsize);
-
-  return(outsize);
+  return chain_reply(inbuf,outbuf,length,bufsize);
 }
 
 
@@ -278,11 +266,8 @@ reply to a session setup command
 ****************************************************************************/
 int reply_sesssetup_and_X(char *inbuf,char *outbuf,int length,int bufsize)
 {
-  int outsize = 0;
   int sess_uid;
   int gid;
-  int   smb_com2;
-  int   smb_off2;       
   int   smb_bufsize;    
   int   smb_mpxmax;     
   int   smb_vc_num;     
@@ -299,8 +284,6 @@ int reply_sesssetup_and_X(char *inbuf,char *outbuf,int length,int bufsize)
   *smb_apasswd = 0;
   
   sess_uid = SVAL(inbuf,smb_uid);
-  smb_com2 = CVAL(inbuf,smb_vwv0);
-  smb_off2 = SVAL(inbuf,smb_vwv1);
   smb_bufsize = SVAL(inbuf,smb_vwv2);
   smb_mpxmax = SVAL(inbuf,smb_vwv3);
   smb_vc_num = SVAL(inbuf,smb_vwv4);
@@ -424,15 +407,15 @@ int reply_sesssetup_and_X(char *inbuf,char *outbuf,int length,int bufsize)
 
   /* it's ok - setup a reply */
   if (Protocol < PROTOCOL_NT1) {
-    outsize = set_message(outbuf,3,0,True);
+    set_message(outbuf,3,0,True);
   } else {
     char *p;
-    outsize = set_message(outbuf,3,3,True);
+    set_message(outbuf,3,3,True);
     p = smb_buf(outbuf);
     strcpy(p,"Unix"); p = skip_string(p,1);
     strcpy(p,"Samba "); strcat(p,VERSION); p = skip_string(p,1);
     strcpy(p,lp_workgroup()); p = skip_string(p,1);
-    outsize = set_message(outbuf,3,PTR_DIFF(p,smb_buf(outbuf)),False);
+    set_message(outbuf,3,PTR_DIFF(p,smb_buf(outbuf)),False);
     /* perhaps grab OS version here?? */
   }
 
@@ -451,9 +434,6 @@ int reply_sesssetup_and_X(char *inbuf,char *outbuf,int length,int bufsize)
     SSVAL(inbuf,smb_uid,(uint16)pw->pw_uid);
   }
 
-  CVAL(outbuf,smb_vwv0) = smb_com2;
-  SSVAL(outbuf,smb_vwv1,(chain_size+outsize)-4);
-
   if (guest && !computer_id)
     SSVAL(outbuf,smb_vwv2,1);
 
@@ -463,12 +443,7 @@ int reply_sesssetup_and_X(char *inbuf,char *outbuf,int length,int bufsize)
  
   maxxmit = MIN(maxxmit,smb_bufsize);
 
-  if (smb_com2 != 0xFF)
-    outsize += chain_reply(smb_com2,inbuf,inbuf+smb_off2+4,
-                          outbuf,outbuf+outsize,
-                          length,bufsize);
-
-  return(outsize);
+  return chain_reply(inbuf,outbuf,length,bufsize);
 }
 
 
@@ -973,10 +948,7 @@ int reply_open_and_X(char *inbuf,char *outbuf,int length,int bufsize)
   pstring fname;
   int cnum = SVAL(inbuf,smb_tid);
   int fnum = -1;
-  int outsize = 0;
   int openmode = 0;
-  int smb_com2 = CVAL(inbuf,smb_vwv0);
-  int smb_off2 = SVAL(inbuf,smb_vwv1);
   int smb_mode = SVAL(inbuf,smb_vwv3);
   int smb_attr = SVAL(inbuf,smb_vwv5);
 #if 0
@@ -1033,9 +1005,7 @@ int reply_open_and_X(char *inbuf,char *outbuf,int length,int bufsize)
     return(ERROR(ERRDOS,ERRnoaccess));
   }
 
-  outsize = set_message(outbuf,15,0,True);
-  CVAL(outbuf,smb_vwv0) = smb_com2;
-  SSVAL(outbuf,smb_vwv1,(chain_size+outsize)-4);
+  set_message(outbuf,15,0,True);
   SSVAL(outbuf,smb_vwv2,fnum);
   SSVAL(outbuf,smb_vwv3,fmode);
   put_dos_date3(outbuf,smb_vwv4,mtime);
@@ -1045,14 +1015,7 @@ int reply_open_and_X(char *inbuf,char *outbuf,int length,int bufsize)
 
   chain_fnum = fnum;
 
-  if (smb_com2 != 0xFF)
-    outsize += chain_reply(smb_com2,inbuf,inbuf+smb_off2+4,
-                          outbuf,outbuf+outsize,
-                          length,bufsize);
-
-  chain_fnum = -1;
-  
-  return(outsize);
+  return chain_reply(inbuf,outbuf,length,bufsize);
 }
 
 
@@ -1061,26 +1024,15 @@ int reply_open_and_X(char *inbuf,char *outbuf,int length,int bufsize)
 ****************************************************************************/
 int reply_ulogoffX(char *inbuf,char *outbuf,int length,int bufsize)
 {
-  int outsize = 0;
-  int smb_com2 = CVAL(inbuf,smb_vwv0);
-  int smb_off2 = SVAL(inbuf,smb_vwv1);
   int uid = SVAL(inbuf,smb_uid);
 
   invalidate_uid(uid);
 
-  outsize = set_message(outbuf,2,0,True);
-  CVAL(outbuf,smb_vwv0) = smb_com2;
-  SSVAL(outbuf,smb_vwv1,(chain_size+outsize)-4);
+  set_message(outbuf,2,0,True);
 
   DEBUG(3,("%s ulogoffX uid=%d\n",timestring(),uid));
 
-  if (smb_com2 != 0xFF)
-    outsize += chain_reply(smb_com2,inbuf,inbuf+smb_off2+4,
-                          outbuf,outbuf+outsize,
-                          length,bufsize);
-
-  
-  return(outsize);
+  return chain_reply(inbuf,outbuf,length,bufsize);
 }
 
 
@@ -1486,8 +1438,6 @@ int reply_read(char *inbuf,char *outbuf)
 ****************************************************************************/
 int reply_read_and_X(char *inbuf,char *outbuf,int length,int bufsize)
 {
-  int smb_com2 = CVAL(inbuf,smb_vwv0);
-  int smb_off2 = SVAL(inbuf,smb_vwv1);
   int fnum = GETFNUM(inbuf,smb_vwv2);
   uint32 smb_offs = IVAL(inbuf,smb_vwv3);
   int smb_maxcnt = SVAL(inbuf,smb_vwv5);
@@ -1495,7 +1445,6 @@ int reply_read_and_X(char *inbuf,char *outbuf,int length,int bufsize)
   int cnum;
   int nread = -1;
   char *data;
-  int outsize = 0;
   BOOL ok = False;
 
   cnum = SVAL(inbuf,smb_tid);
@@ -1504,7 +1453,7 @@ int reply_read_and_X(char *inbuf,char *outbuf,int length,int bufsize)
   CHECK_READ(fnum);
   CHECK_ERROR(fnum);
 
-  outsize = set_message(outbuf,12,0,True);
+  set_message(outbuf,12,0,True);
   data = smb_buf(outbuf);
 
   if (is_locked(fnum,cnum,smb_maxcnt,smb_offs))
@@ -1515,27 +1464,17 @@ int reply_read_and_X(char *inbuf,char *outbuf,int length,int bufsize)
   if (nread < 0)
     return(UNIXERROR(ERRDOS,ERRnoaccess));
   
-  outsize += nread;
-  CVAL(outbuf,smb_vwv0) = smb_com2;
-  SSVAL(outbuf,smb_vwv1,(outsize+chain_size)-4);
   SSVAL(outbuf,smb_vwv5,nread);
-  SSVAL(outbuf,smb_vwv6,smb_offset(data,outbuf) + chain_size);
+  SSVAL(outbuf,smb_vwv6,smb_offset(data,outbuf));
   SSVAL(smb_buf(outbuf),-2,nread);
   
-  DEBUG(3,("%s readX fnum=%d cnum=%d min=%d max=%d nread=%d com2=%d off2=%d\n",
+  DEBUG(3,("%s readX fnum=%d cnum=%d min=%d max=%d nread=%d\n",
        timestring(),fnum,cnum,
-       smb_mincnt,smb_maxcnt,nread,smb_com2,smb_off2));
+       smb_mincnt,smb_maxcnt,nread));
 
   chain_fnum = fnum;
 
-  if (smb_com2 != 0xFF)
-    outsize += chain_reply(smb_com2,inbuf,inbuf+smb_off2+4,
-                          outbuf,outbuf+outsize,
-                          length,bufsize);
-  
-  chain_fnum = -1;
-  
-  return(outsize);
+  return chain_reply(inbuf,outbuf,length,bufsize);
 }
 
 
@@ -1767,8 +1706,6 @@ int reply_write(char *inbuf,char *outbuf,int dum1,int dum2)
 ****************************************************************************/
 int reply_write_and_X(char *inbuf,char *outbuf,int length,int bufsize)
 {
-  int smb_com2 = CVAL(inbuf,smb_vwv0);
-  int smb_off2 = SVAL(inbuf,smb_vwv1);
   int fnum = GETFNUM(inbuf,smb_vwv2);
   uint32 smb_offs = IVAL(inbuf,smb_vwv3);
   int smb_dsize = SVAL(inbuf,smb_vwv10);
@@ -1776,7 +1713,6 @@ int reply_write_and_X(char *inbuf,char *outbuf,int length,int bufsize)
   BOOL write_through = BITSETW(inbuf+smb_vwv7,0);
   int cnum;
   int nwritten = -1;
-  int outsize = 0;
   char *data;
 
   cnum = SVAL(inbuf,smb_tid);
@@ -1804,10 +1740,8 @@ int reply_write_and_X(char *inbuf,char *outbuf,int length,int bufsize)
   if(((nwritten == 0) && (smb_dsize != 0))||(nwritten < 0))
     return(UNIXERROR(ERRDOS,ERRnoaccess));
 
-  outsize = set_message(outbuf,6,0,True);
+  set_message(outbuf,6,0,True);
   
-  CVAL(outbuf,smb_vwv0) = smb_com2;
-  SSVAL(outbuf,smb_vwv1,(outsize+chain_size)-4);
   SSVAL(outbuf,smb_vwv2,nwritten);
   
   if (nwritten < smb_dsize) {
@@ -1822,14 +1756,7 @@ int reply_write_and_X(char *inbuf,char *outbuf,int length,int bufsize)
   if (lp_syncalways(SNUM(cnum)) || write_through)
     sync_file(fnum);
 
-  if (smb_com2 != 0xFF)
-    outsize += chain_reply(smb_com2,inbuf,inbuf+smb_off2+4,
-                          outbuf,outbuf+outsize,
-                          length,bufsize);
-  
-  chain_fnum = -1;
-  
-  return(outsize);
+  return chain_reply(inbuf,outbuf,length,bufsize);
 }
 
 
@@ -2828,8 +2755,6 @@ int reply_setdir(char *inbuf,char *outbuf)
 ****************************************************************************/
 int reply_lockingX(char *inbuf,char *outbuf,int length,int bufsize)
 {
-  int smb_com2 = CVAL(inbuf,smb_vwv0);
-  int smb_off2 = SVAL(inbuf,smb_vwv1);
   int fnum = GETFNUM(inbuf,smb_vwv2);
   uint16 locktype = SVAL(inbuf,smb_vwv3);
   uint16 num_ulocks = SVAL(inbuf,smb_vwv6);
@@ -2840,7 +2765,7 @@ int reply_lockingX(char *inbuf,char *outbuf,int length,int bufsize)
   int i;
   char *data;
   uint32 ecode=0, dummy2;
-  int outsize, eclass=0, dummy1;
+  int eclass=0, dummy1;
 
   cnum = SVAL(inbuf,smb_tid);
 
@@ -2879,24 +2804,14 @@ int reply_lockingX(char *inbuf,char *outbuf,int length,int bufsize)
     return ERROR(eclass,ecode);
   }
 
-  outsize = set_message(outbuf,2,0,True);
-  
-  CVAL(outbuf,smb_vwv0) = smb_com2;
-  SSVAL(outbuf,smb_vwv1,(outsize+chain_size)-4);
+  set_message(outbuf,2,0,True);
   
   DEBUG(3,("%s lockingX fnum=%d cnum=%d type=%d num_locks=%d num_ulocks=%d\n",
        timestring(),fnum,cnum,locktype,num_locks,num_ulocks));
 
   chain_fnum = fnum;
 
-  if (smb_com2 != 0xFF)
-    outsize += chain_reply(smb_com2,inbuf,inbuf+smb_off2+4,
-                          outbuf,outbuf+outsize,
-                          length,bufsize);
-  
-  chain_fnum = -1;
-  
-  return(outsize);
+  return chain_reply(inbuf,outbuf,length,bufsize);
 }
 
 
index 403b41e86b59f8a1e2e7ee165ff822e8a5a648c3..c3776845361f2c0c960ebb07921f7918d27c2f16 100644 (file)
@@ -59,8 +59,6 @@ extern int Protocol;
 
 int maxxmit = BUFFER_SIZE;
 
-int chain_size = 0;
-
 /* a fnum to use when chaining */
 int chain_fnum = -1;
 
@@ -1645,7 +1643,7 @@ static BOOL open_sockets(BOOL is_daemon,int port)
 #endif
 
       /* open an incoming socket */
-      s = open_socket_in(SOCK_STREAM, port, 0);
+      s = open_socket_in(SOCK_STREAM, port, 0,interpret_addr(lp_socket_address()));
       if (s == -1)
        return(False);
 
@@ -3221,103 +3219,97 @@ static int switch_message(int type,char *inbuf,char *outbuf,int size,int bufsize
 
 
 /****************************************************************************
-construct a chained reply and add it to the already made reply
-
-inbuf points to the original message start.
-inbuf2 points to the smb_wct part of the secondary message
-type is the type of the secondary message
-outbuf points to the original outbuffer
-outbuf2 points to the smb_wct field of the new outbuffer
-size is the total length of the incoming message (from inbuf1)
-bufsize is the total buffer size
-
-return how many bytes were added to the response
-****************************************************************************/
-int chain_reply(int type,char *inbuf,char *inbuf2,char *outbuf,char *outbuf2,int size,int bufsize)
-{
-  int outsize = 0;
-  char *ibuf,*obuf;
-  static BOOL in_chain = False;
-  static char *last_outbuf=NULL;
-  BOOL was_inchain = in_chain;
-  int insize_remaining;
-  static int insize_deleted;
-
-  chain_size += PTR_DIFF(outbuf2,outbuf) - smb_wct;
-  if (was_inchain)
-    outbuf = last_outbuf;
-  else
-    insize_deleted = 0;
-
+  construct a chained reply and add it to the already made reply
+  **************************************************************************/
+int chain_reply(char *inbuf,char *outbuf,int size,int bufsize)
+{
+  static char *orig_inbuf;
+  static char *orig_outbuf;
+  int smb_com2 = CVAL(inbuf,smb_vwv0);
+  unsigned smb_off2 = SVAL(inbuf,smb_vwv1);
+  char *inbuf2, *outbuf2;
+  int outsize2;
+  char inbuf_saved[smb_wct];
+  char outbuf_saved[smb_wct];
+  extern int chain_size;
+  int wct = CVAL(outbuf,smb_wct);
+  int outsize = smb_size + 2*wct + SVAL(outbuf,smb_vwv0+2*wct);
+
+  /* maybe its not chained */
+  if (smb_com2 == 0xFF) {
+    CVAL(outbuf,smb_vwv0) = 0xFF;
+    return outsize;
+  }
 
-  insize_deleted = 0;
-  inbuf2 -= insize_deleted;
-  insize_remaining = size - PTR_DIFF(inbuf2,inbuf);
-  insize_deleted += size - (insize_remaining + smb_wct);
+  if (chain_size == 0) {
+    /* this is the first part of the chain */
+    orig_inbuf = inbuf;
+    orig_outbuf = outbuf;
+  }
 
-  in_chain = True;
-  last_outbuf = outbuf;
+  /* we need to tell the client where the next part of the reply will be */
+  SSVAL(outbuf,smb_vwv1,smb_offset(outbuf+outsize,outbuf));
+  CVAL(outbuf,smb_vwv0) = smb_com2;
 
+  /* remember how much the caller added to the chain, only counting stuff
+     after the parameter words */
+  chain_size += outsize - smb_wct;
 
-  /* allocate some space for the in and out buffers of the chained message */
-  ibuf = (char *)malloc(size + SAFETY_MARGIN);
-  obuf = (char *)malloc(bufsize + SAFETY_MARGIN);
+  /* work out pointers into the original packets. The
+     headers on these need to be filled in */
+  inbuf2 = orig_inbuf + smb_off2 + 4 - smb_wct;
+  outbuf2 = orig_outbuf + SVAL(outbuf,smb_vwv1) + 4 - smb_wct;
 
-  if (!ibuf || !obuf)
-    {
-      DEBUG(0,("Out of memory in chain reply\n"));
-      return(ERROR(ERRSRV,ERRnoresource));
-    }
+  /* save the data which will be overwritten by the new headers */
+  memcpy(inbuf_saved,inbuf2,smb_wct);
+  memcpy(outbuf_saved,outbuf2,smb_wct);
 
-  ibuf += SMB_ALIGNMENT;
-  obuf += SMB_ALIGNMENT;
+  /* give the new packet the same header as the first part of the SMB */
+  memcpy(inbuf2,orig_inbuf,smb_wct);
 
   /* create the in buffer */
-  memcpy(ibuf,inbuf,smb_wct);
-  memcpy(ibuf+smb_wct,inbuf2,insize_remaining);
-  CVAL(ibuf,smb_com) = type;
+  CVAL(outbuf2,smb_com) = smb_com2;
 
   /* create the out buffer */
-  bzero(obuf,smb_size);
-
-  set_message(obuf,0,0,True);
-  CVAL(obuf,smb_com) = CVAL(ibuf,smb_com);
+  bzero(outbuf2,smb_size);
+  set_message(outbuf2,0,0,True);
+  CVAL(outbuf2,smb_com) = CVAL(inbuf2,smb_com);
   
-  memcpy(obuf+4,ibuf+4,4);
-  CVAL(obuf,smb_rcls) = SUCCESS;
-  CVAL(obuf,smb_reh) = 0;
-  CVAL(obuf,smb_flg) = 0x80 | (CVAL(ibuf,smb_flg) & 0x8); /* bit 7 set 
-                                                            means a reply */
-  SSVAL(obuf,smb_flg2,1); /* say we support long filenames */
-  SSVAL(obuf,smb_err,SUCCESS);
-  SSVAL(obuf,smb_tid,SVAL(inbuf,smb_tid));
-  SSVAL(obuf,smb_pid,SVAL(inbuf,smb_pid));
-  SSVAL(obuf,smb_uid,SVAL(inbuf,smb_uid));
-  SSVAL(obuf,smb_mid,SVAL(inbuf,smb_mid));
+  memcpy(outbuf2+4,inbuf2+4,4);
+  CVAL(outbuf2,smb_rcls) = SUCCESS;
+  CVAL(outbuf2,smb_reh) = 0;
+  CVAL(outbuf2,smb_flg) = 0x80 | (CVAL(inbuf2,smb_flg) & 0x8); /* bit 7 set 
+                                                                 means a reply */
+  SSVAL(outbuf2,smb_flg2,1); /* say we support long filenames */
+  SSVAL(outbuf2,smb_err,SUCCESS);
+  SSVAL(outbuf2,smb_tid,SVAL(inbuf2,smb_tid));
+  SSVAL(outbuf2,smb_pid,SVAL(inbuf2,smb_pid));
+  SSVAL(outbuf2,smb_uid,SVAL(inbuf2,smb_uid));
+  SSVAL(outbuf2,smb_mid,SVAL(inbuf2,smb_mid));
 
   DEBUG(3,("Chained message\n"));
-  show_msg(ibuf);
+  show_msg(inbuf2);
 
   /* process the request */
-  outsize = switch_message(type,ibuf,obuf,smb_wct+insize_remaining,
-                          bufsize-chain_size);
+  outsize2 = switch_message(smb_com2,inbuf2,outbuf2,size-chain_size,
+                           bufsize-chain_size);
 
   /* copy the new reply header over the old one, but preserve 
      the smb_com field */
-  memcpy(outbuf+smb_com+1,obuf+smb_com+1,smb_wct-(smb_com+1));
-
-  /* and copy the data from the reply to the right spot */
-  memcpy(outbuf2,obuf+smb_wct,outsize - smb_wct);
-
-  /* free the allocated buffers */
-  if (ibuf) free(ibuf-SMB_ALIGNMENT);
-  if (obuf) free(obuf-SMB_ALIGNMENT);
+  smb_com2 = CVAL(orig_outbuf,smb_com);
+  memmove(orig_outbuf,outbuf2,smb_wct);
+  CVAL(orig_outbuf,smb_com) = smb_com2;
 
-  in_chain = was_inchain;
+  /* restore the saved data, being careful not to overwrite any
+   data from the reply header */
+  memcpy(inbuf2,inbuf_saved,smb_wct);
+  {
+    int ofs = smb_wct - PTR_DIFF(outbuf2,orig_outbuf);
+    if (ofs < 0) ofs = 0;
+    memmove(outbuf2+ofs,outbuf_saved+ofs,smb_wct-ofs);
+  }
 
-  /* return how much extra has been added to the packet */
-  return(outsize - smb_wct);
+  return(outsize2 + chain_size);
 }
 
 
@@ -3330,10 +3322,12 @@ int construct_reply(char *inbuf,char *outbuf,int size,int bufsize)
   int type = CVAL(inbuf,smb_com);
   int outsize = 0;
   int msg_type = CVAL(inbuf,0);
+  extern int chain_size;
 
   smb_last_time = time(NULL);
 
   chain_size = 0;
+  chain_fnum = -1;
 
   bzero(outbuf,smb_size);
 
index 292b526df9346709833064737b219a38a371dfad..d418814a69bf4c88f988de549ee95d74fc735a6c 100644 (file)
@@ -49,7 +49,7 @@ static BOOL open_sockets(void)
       return False;
     }   
 
-  ServerFD = open_socket_in(SOCK_DGRAM, 0,3);
+  ServerFD = open_socket_in(SOCK_DGRAM, 0,3,interpret_addr(lp_socket_address()));
 
   if (ServerFD == -1)
     return(False);