Hi.

I suggest the following small SAMBA code improvement in printing area.

 

All known SAMBA versions can't return to Windows client any return code after calling "print command".

I need it therefore I made the following SAMBA changes:

 

  1. Change prototype of function "print_job_end" (in file "proto.h"):

int print_job_end(int jobid, BOOL normal_close);

  1. Add new error into file "doserr.h"

#define ERRfiledeleted 63 /* Your file waiting to be printed was deleted.  */

I try to use this code in case of errors happened before calling "print command"

  1. Change function "print_job_end" in file "printing.c":

 

/*  return codes -1 means error before call current_printif->job_submit, 0 means that job_submit was called OK,

 * other positive codes means job_submit was called and brings this error code */

int print_job_end(int jobid, BOOL normal_close)

{

            struct printjob *pjob = print_job_find(jobid);

            int snum, ret = 0;

            SMB_STRUCT_STAT sbuf;

 

            if (!pjob)

        return -1;

 

            if (pjob->spooled || pjob->pid != local_pid)

        return -1;

 

            snum = print_job_snum(jobid);

 

            if (normal_close && (sys_fstat(pjob->fd, &sbuf) == 0)) {

                        pjob->size = sbuf.st_size;

                        close(pjob->fd);

                        pjob->fd = -1;

            } else {

 

                        /*

                         * Not a normal close or we couldn't stat the job file,

                         * so something has gone wrong. Cleanup.

                         */

                        close(pjob->fd);

                        pjob->fd = -1;

                        DEBUG(3,("print_job_end: failed to stat file for jobid %d\n", jobid ));

                        goto fail;

            }

 

            /* Technically, this is not quit right. If the printer has a separator

             * page turned on, the NT spooler prints the separator page even if the

             * print job is 0 bytes. 010215 JRR */

            if (pjob->size == 0 || pjob->status == LPQ_DELETING) {

                        /* don't bother spooling empty files or something being deleted. */

                        DEBUG(5,("print_job_end: canceling spool of %s (%s)\n",

                                    pjob->filename, pjob->size ? "deleted" : "zero length" ));

                        unlink(pjob->filename);

                        tdb_delete(tdb, print_key(jobid));

                return 0;

            }

 

            ret = (*(current_printif->job_submit))(snum, pjob);

 

            if (ret)

                        goto fail;

 

            /* The print job has been sucessfully handed over to the back-end */

 

            pjob->spooled = True;

            pjob->status = LPQ_QUEUED;

            print_job_store(jobid, pjob);

 

            /* make sure the database is up to date */

            if (print_cache_expired(snum))

                        print_queue_update(snum);

 

        return ret;                         /* must be 0 */

 

fail:

 

            /* The print job was not succesfully started. Cleanup */

            /* Still need to add proper error return propagation! 010122:JRR */

            unlink(pjob->filename);

            tdb_delete(tdb, print_key(jobid));

        if ( ret == 0) {                    /* current_printif->job_submit  was not called */

          return -1;

        }

        return ret;

}

 

  1. Change function "spoolss_enddocprinter_internal" in file "srv_spoolss_nt.c":  

static uint32 _spoolss_enddocprinter_internal(pipes_struct *p, POLICY_HND *handle)

{

    int rc;

    Printer_entry *Printer=find_printer_index_by_hnd(p, handle);

 

            if (!Printer) {

                        DEBUG(0,("_spoolss_enddocprinter_internal: Invalid handle (%s)\n", OUR_HANDLE(handle)));

                        return ERRbadfid;

            }

 

            Printer->document_started=False;

    rc = print_job_end(Printer->jobid,True);

    if ( rc != 0) {

        DEBUG(0,("_spoolss_enddocprinter_internal: print_job_end returns, %d \n", rc));

    }else{

        DEBUG(3,("_spoolss_enddocprinter_internal: print_job_end returns, %d \n", rc));

    }

    if ( rc == -1) {

      rc = ERRfiledeleted;  /* It means that any problem happened before calling "print command"  */

    }

    return rc;

}

 

 

I have made it, compiled and installed on Debian Linux. It works fine and brings error codes to Windows clients.

Main assumption here: The "print command" returns 0 if job submitted OK and valid Windows/Dos error code in other cases.

Best regards

            Arcady

 

[EMAIL PROTECTED]

 

 

Reply via email to