r925: add changes frpm trunk (r841 and r842) -- enable background queue update proces...
authorGerald Carter <jerry@samba.org>
Thu, 27 May 2004 15:38:54 +0000 (15:38 +0000)
committerGerald (Jerry) Carter <jerry@samba.org>
Wed, 10 Oct 2007 15:51:49 +0000 (10:51 -0500)
(This used to be commit 066b9c4276a968788a03709a00d4f672ac032df7)

source3/include/messages.h
source3/printing/notify.c
source3/printing/printing.c
source3/rpc_server/srv_spoolss_nt.c
source3/smbd/server.c

index 37e9372cdaada42dba7f33f22a4b3cbe96502c86..78f19fa0bdbde4679a966ae9cdab0fc33b9de29b 100644 (file)
 
 /* printing messages */
 /* #define MSG_PRINTER_NOTIFY  2001*/ /* Obsolete */
-#define MSG_PRINTER_DRVUPGRADE 2002
-#define MSG_PRINTER_NOTIFY2     2003
+#define MSG_PRINTER_DRVUPGRADE         2002
+#define MSG_PRINTER_NOTIFY2            2003
 #define MSG_PRINTERDATA_INIT_RESET     2004
+#define MSG_PRINTER_UPDATE             2005
 
 /* smbd messages */
 #define MSG_SMB_CONF_UPDATED 3001
index 7750239630cabfa04878a2410a90279ca36dc76b..26ef191f877a4c9d1b5b363493d196573ae61c1b 100644 (file)
@@ -463,6 +463,15 @@ void notify_printer_sharename(int snum, char *share_name)
                snum, strlen(share_name) + 1, share_name);
 }
 
+void notify_printer_printername(int snum, char *printername)
+{
+       const char *printer_name = SERVICE(snum);
+
+       send_notify_field_buffer(
+               printer_name, PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_PRINTER_NAME,
+               snum, strlen(printername) + 1, printername);
+}
+
 void notify_printer_port(int snum, char *port_name)
 {
        const char *printer_name = SERVICE(snum);
index 2355dd14506bac1acc73639a37a01617cb934507..670e489786c7916e1df78b0789b464c2da2d3425 100644 (file)
@@ -23,6 +23,9 @@
 #include "includes.h"
 #include "printing.h"
 
+extern SIG_ATOMIC_T got_sig_term;
+extern SIG_ATOMIC_T reload_after_sighup;
+
 /* Current printer interface */
 static BOOL remove_from_jobs_changed(int snum, uint32 jobid);
 
@@ -971,7 +974,7 @@ static void check_job_changed(int snum, TDB_DATA data, uint32 jobid)
  Update the internal database from the system print queue for a queue.
 ****************************************************************************/
 
-static void print_queue_update(int snum)
+static void print_queue_update_internal(int snum)
 {
        int i, qcount;
        print_queue_struct *queue = NULL;
@@ -1150,6 +1153,89 @@ static void print_queue_update(int snum)
        release_print_db(pdb);
 }
 
+/****************************************************************************
+this is the receive function of the background lpq updater
+****************************************************************************/
+static void print_queue_receive(int msg_type, pid_t src, void *buf, size_t len)
+{
+       int snum;
+       snum=*((int *)buf);
+       print_queue_update_internal(snum);
+}
+
+static pid_t background_lpq_updater_pid = -1;
+
+/****************************************************************************
+main thread of the background lpq updater
+****************************************************************************/
+void start_background_queue(void)
+{
+       DEBUG(3,("start_background_queue: Starting background LPQ thread\n"));
+       background_lpq_updater_pid = sys_fork();
+
+       if (background_lpq_updater_pid == -1) {
+               DEBUG(5,("start_background_queue: background LPQ thread failed to start. %s\n", strerror(errno) ));
+               exit(1);
+       }
+
+       if(background_lpq_updater_pid == 0) {
+               /* Child. */
+               DEBUG(5,("start_background_queue: background LPQ thread started\n"));
+
+               claim_connection( NULL, "smbd lpq backend", 0, False, 
+                       FLAG_MSG_GENERAL|FLAG_MSG_SMBD|FLAG_MSG_PRINTING );
+
+               if (!locking_init(0)) {
+                       exit(1);
+               }
+
+               if (!print_backend_init()) {
+                       exit(1);
+               }
+
+               message_register(MSG_PRINTER_UPDATE, print_queue_receive);
+               
+               DEBUG(5,("start_background_queue: background LPQ thread waiting for messages\n"));
+               while (1) {
+                       pause();
+                       
+                       /* check for some essential signals first */
+                       
+                        if (got_sig_term) {
+                                exit_server("Caught TERM signal");
+                        }
+
+                        if (reload_after_sighup) {
+                                change_to_root_user();
+                                DEBUG(1,("Reloading services after SIGHUP\n"));
+                                reload_services(False);
+                                reload_after_sighup = 0;
+                        }
+                       
+                       /* now check for messages */
+                       
+                       DEBUG(10,("start_background_queue: background LPQ thread got a message\n"));
+                       message_dispatch();
+               }
+       }
+}
+
+/****************************************************************************
+update the internal database from the system print queue for a queue
+****************************************************************************/
+static void print_queue_update(int snum)
+{
+       /* 
+        * Make sure that the backgroup queueu process exists.  
+        * Otherwise just do the update ourselves 
+        */
+          
+       if ( background_lpq_updater_pid != -1 )
+               message_send_pid(background_lpq_updater_pid, MSG_PRINTER_UPDATE, &snum, sizeof(snum), False);
+       else
+               print_queue_update_internal( snum );
+}
+
 /****************************************************************************
  Create/Update an entry in the print tdb that will allow us to send notify
  updates only to interested smbd's. 
index 3b1bb5ede5deb67b8182e9d3a0d9a3f9a64848a0..a6d47a46c32552250453ab50defbd381b0d9471e 100644 (file)
@@ -473,9 +473,11 @@ static BOOL set_printer_hnd_name(Printer_entry *Printer, char *handlename)
 {
        int snum;
        int n_services=lp_numservices();
-       char *aprinter;
+       char *aprinter, *printername;
        fstring sname;
        BOOL found=False;
+       NT_PRINTER_INFO_LEVEL *printer;
+       WERROR result;
        
        DEBUG(4,("Setting printer name=%s (len=%lu)\n", handlename, (unsigned long)strlen(handlename)));
 
@@ -496,31 +498,56 @@ static BOOL set_printer_hnd_name(Printer_entry *Printer, char *handlename)
                aprinter=handlename;
        }
 
-       DEBUGADD(5,("searching for [%s] (len=%lu)\n", aprinter, (unsigned long)strlen(aprinter)));
+       DEBUGADD(5, ("searching for [%s] (len=%lu)\n", aprinter, (unsigned long)strlen(aprinter)));
 
-       /*
-        * The original code allowed smbd to store a printer name that
-        * was different from the share name.  This is not possible 
-        * anymore, so I've simplified this loop greatly.  Here
-        * we are just verifying that the printer name is a valid
-        * printer service defined in smb.conf
-        *                          --jerry [Fri Feb 15 11:17:46 CST 2002]
-        */
+       /* have to search on sharename and PRINTER_INFO2->printername */
 
        for (snum=0; snum<n_services; snum++) {
 
                if ( !(lp_snum_ok(snum) && lp_print_ok(snum) ) )
                        continue;
                
+               /* ------ sharename ------ */
+
                fstrcpy(sname, lp_servicename(snum));
 
-               DEBUGADD(5,("share:%s\n",sname));
+               DEBUGADD(10, ("share: %s\n",sname));
                
-               if (! StrCaseCmp(sname, aprinter)) {
+               if ( strequal(sname, aprinter) ) {
                        found = True;
                        break;
                }
+               
+               /* ------ printername ------ */
 
+               printer = NULL;
+               result = get_a_printer( NULL, &printer, 2, sname );
+               if ( !W_ERROR_IS_OK(result) ) {
+                       DEBUG(0,("set_printer_hnd_name: failed to lookup printer [%s] -- result [%s]\n",
+                               sname, dos_errstr(result)));
+                       continue;
+               }
+               
+               /* printername is always returned as \\server\printername */
+               if ( !(printername = strchr_m(&printer->info_2->printername[2], '\\')) ) {
+                       DEBUG(0,("set_printer_hnd_name: info2->printername in wrong format! [%s]\n",
+                               printer->info_2->printername));
+                       free_a_printer( &printer, 2);
+                       continue;
+               }
+               
+               printername++;
+                       
+               if ( strequal(printername, aprinter) ) {
+                       found = True;
+               }
+               
+               DEBUGADD(10, ("printername: %s\n", printername));
+               
+               free_a_printer( &printer, 2);
+               
+               if ( found )
+                       break;
        }
 
                
@@ -5854,14 +5881,28 @@ static WERROR update_printer_sec(POLICY_HND *handle, uint32 level,
 
 static BOOL check_printer_ok(NT_PRINTER_INFO_LEVEL_2 *info, int snum)
 {
+       fstring printername;
+       const char *p;
+       
        DEBUG(5,("check_printer_ok: servername=%s printername=%s sharename=%s portname=%s drivername=%s comment=%s location=%s\n",
                 info->servername, info->printername, info->sharename, info->portname, info->drivername, info->comment, info->location));
 
        /* we force some elements to "correct" values */
        slprintf(info->servername, sizeof(info->servername)-1, "\\\\%s", get_called_name());
        fstrcpy(info->sharename, lp_servicename(snum));
+       
+       /* make sure printername is in \\server\printername format */
+       
+       fstrcpy( printername, info->printername );
+       p = printername;
+       if ( printername[0] == '\\' && printername[1] == '\\' ) {
+               if ( (p = strchr_m( &printername[2], '\\' )) != NULL )
+                       p++;
+       }
+       
        slprintf(info->printername, sizeof(info->printername)-1, "\\\\%s\\%s",
-                get_called_name(), info->sharename);
+                get_called_name(), p );
+                
        info->attributes = PRINTER_ATTRIBUTE_SAMBA;
        
        
@@ -6057,14 +6098,28 @@ static WERROR update_printer(pipes_struct *p, POLICY_HND *handle, uint32 level,
 
        if (!strequal(printer->info_2->sharename, old_printer->info_2->sharename)) {
                init_unistr2( &buffer, printer->info_2->sharename, UNI_STR_TERMINATE);
-               set_printer_dataex( printer, SPOOL_DSSPOOLER_KEY, "printerName",
-                       REG_SZ, (uint8*)buffer.buffer, buffer.uni_str_len*2 );
                set_printer_dataex( printer, SPOOL_DSSPOOLER_KEY, "shareName",
                        REG_SZ, (uint8*)buffer.buffer, buffer.uni_str_len*2 );
 
                notify_printer_sharename(snum, printer->info_2->sharename);
        }
 
+       if (!strequal(printer->info_2->printername, old_printer->info_2->printername)) {
+               char *pname;
+               
+               if ( (pname = strchr_m( printer->info_2->printername+2, '\\' )) != NULL )
+                       pname++;
+               else
+                       pname = printer->info_2->printername;
+                       
+
+               init_unistr2( &buffer, pname, UNI_STR_TERMINATE);
+               set_printer_dataex( printer, SPOOL_DSSPOOLER_KEY, "printerName",
+                       REG_SZ, (uint8*)buffer.buffer, buffer.uni_str_len*2 );
+
+               notify_printer_printername( snum, pname );
+       }
+       
        if (!strequal(printer->info_2->portname, old_printer->info_2->portname)) {
                init_unistr2( &buffer, printer->info_2->portname, UNI_STR_TERMINATE);
                set_printer_dataex( printer, SPOOL_DSSPOOLER_KEY, "portName",
@@ -8750,19 +8805,19 @@ WERROR _spoolss_setprinterdataex(pipes_struct *p, SPOOL_Q_SETPRINTERDATAEX *q_u,
        {
                /* save the OID if one was specified */
                if ( oid_string ) {
-               fstrcat( keyname, "\\" );
-               fstrcat( keyname, SPOOL_OID_KEY );
+                       fstrcat( keyname, "\\" );
+                       fstrcat( keyname, SPOOL_OID_KEY );
                
-               /* 
-                * I'm not checking the status here on purpose.  Don't know 
-                * if this is right, but I'm returning the status from the 
-                * previous set_printer_dataex() call.  I have no idea if 
-                * this is right.    --jerry
-                */
+                       /* 
+                        * I'm not checking the status here on purpose.  Don't know 
+                        * if this is right, but I'm returning the status from the 
+                        * previous set_printer_dataex() call.  I have no idea if 
+                        * this is right.    --jerry
+                        */
                 
-               set_printer_dataex( printer, keyname, valuename, 
-                                   REG_SZ, (void*)oid_string, strlen(oid_string)+1 );          
-       }
+                       set_printer_dataex( printer, keyname, valuename, 
+                                           REG_SZ, (void*)oid_string, strlen(oid_string)+1 );          
+               }
        
                status = mod_a_printer(*printer, 2);
        }
index f25d42711db38a25f18d9a8e00d43f81cc62021e..343a835be8a51f2c55799f89158132bac8619438 100644 (file)
@@ -849,12 +849,13 @@ void build_options(BOOL screen);
        /* Setup the main smbd so that we can get messages. */
        claim_connection(NULL,"",0,True,FLAG_MSG_GENERAL|FLAG_MSG_SMBD);
 
-       /* 
-          DO NOT ENABLE THIS TILL YOU COPE WITH KILLING THESE TASKS AND INETD
-          THIS *killed* LOTS OF BUILD FARM MACHINES. IT CREATED HUNDREDS OF 
-          smbd PROCESSES THAT NEVER DIE
-          start_background_queue(); 
-       */
+       /* only start the background queue daemon if we are 
+          running as a daemon -- bad things will happen if
+          smbd is launched via inetd and we fork a copy of 
+          ourselves here */
+
+       if ( is_daemon )
+               start_background_queue(); 
 
        if (!open_sockets_smbd(is_daemon, interactive, ports))
                exit(1);