Merge branch 'master' of ssh://git.samba.org/data/git/samba into regsrv
[ab/samba.git/.git] / source3 / printing / printfsp.c
index 2ec8de683585d3d57dd5579f4af34fde085a7a3a..a247cd84276106e7a819bffdc0b9789b15fd0eb3 100644 (file)
@@ -1,13 +1,12 @@
 /* 
-   Unix SMB/Netbios implementation.
-   Version 3.0
+   Unix SMB/CIFS implementation.
    printing backend routines for smbd - using files_struct rather
    than only snum
    Copyright (C) Andrew Tridgell 1992-2000
    
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
-   the Free Software Foundation; either version 2 of the License, or
+   the Free Software Foundation; either version 3 of the License, or
    (at your option) any later version.
    
    This program is distributed in the hope that it will be useful,
    GNU General Public License for more details.
    
    You should have received a copy of the GNU General Public License
-   along with this program; if not, write to the Free Software
-   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
 
 #include "includes.h"
-extern int DEBUGLEVEL;
-
 
 /***************************************************************************
 open a print file and setup a fsp for it. This is a wrapper around
 print_job_start().
 ***************************************************************************/
 
-files_struct *print_fsp_open(connection_struct *conn)
+NTSTATUS print_fsp_open(struct smb_request *req, connection_struct *conn,
+                       const char *fname,
+                       uint16_t current_vuid, files_struct **result)
 {
        int jobid;
        SMB_STRUCT_STAT sbuf;
-       extern struct current_user current_user;
-       files_struct *fsp = file_new(conn);
+       files_struct *fsp;
+       fstring name;
+       NTSTATUS status;
+
+       status = file_new(req, conn, &fsp);
+       if(!NT_STATUS_IS_OK(status)) {
+               return status;
+       }
 
-       if(!fsp)
-               return NULL;
+       fstrcpy( name, "Remote Downlevel Document");
+       if (fname) {
+               const char *p = strrchr(fname, '/');
+               fstrcat(name, " ");
+               if (!p) {
+                       p = fname;
+               }
+               fstrcat(name, p);
+       }
 
-       jobid = print_job_start(&current_user, SNUM(conn), "smb.prn");
+       jobid = print_job_start(conn->server_info, SNUM(conn), name, NULL);
        if (jobid == -1) {
-               file_free(fsp);
-               return NULL;
+               status = map_nt_error_from_unix(errno);
+               file_free(req, fsp);
+               return status;
+       }
+
+       /* Convert to RAP id. */
+       fsp->rap_print_jobid = pjobid_to_rap(lp_const_servicename(SNUM(conn)), jobid);
+       if (fsp->rap_print_jobid == 0) {
+               /* We need to delete the entry in the tdb. */
+               pjob_delete(lp_const_servicename(SNUM(conn)), jobid);
+               file_free(req, fsp);
+               return NT_STATUS_ACCESS_DENIED; /* No errno around here */
        }
 
        /* setup a full fsp */
-       fsp->print_jobid = jobid;
-       fsp->fd = print_job_fd(jobid);
+       fsp->fh->fd = print_job_fd(lp_const_servicename(SNUM(conn)),jobid);
        GetTimeOfDay(&fsp->open_time);
-       fsp->vuid = current_user.vuid;
-       fsp->size = 0;
-       fsp->pos = -1;
+       fsp->vuid = current_vuid;
+       fsp->fh->pos = -1;
        fsp->can_lock = True;
        fsp->can_read = False;
+       fsp->access_mask = FILE_GENERIC_WRITE;
        fsp->can_write = True;
-       fsp->share_mode = 0;
        fsp->print_file = True;
        fsp->modified = False;
        fsp->oplock_type = NO_OPLOCK;
        fsp->sent_oplock_break = NO_BREAK_SENT;
        fsp->is_directory = False;
-       fsp->stat_open = False;
-       fsp->directory_delete_on_close = False;
-       fsp->conn = conn;
-       string_set(&fsp->fsp_name,print_job_fname(jobid));
+       string_set(&fsp->fsp_name,print_job_fname(lp_const_servicename(SNUM(conn)),jobid));
        fsp->wcp = NULL; 
-       conn->vfs_ops.fstat(fsp,fsp->fd, &sbuf);
+       SMB_VFS_FSTAT(fsp, &sbuf);
        fsp->mode = sbuf.st_mode;
-       fsp->inode = sbuf.st_ino;
-       fsp->dev = sbuf.st_dev;
+       fsp->file_id = vfs_file_id_from_sbuf(conn, &sbuf);
 
        conn->num_files_open++;
 
-       return fsp;
+       *result = fsp;
+       return NT_STATUS_OK;
 }
 
 /****************************************************************************
-print a file - called on closing the file
+ Print a file - called on closing the file.
 ****************************************************************************/
-void print_fsp_end(files_struct *fsp, BOOL normal_close)
+
+void print_fsp_end(files_struct *fsp, enum file_close_type close_type)
 {
-       if (fsp->share_mode == FILE_DELETE_ON_CLOSE) {
+       uint32 jobid;
+       fstring sharename;
+
+       if (fsp->fh->private_options & FILE_DELETE_ON_CLOSE) {
                /*
                 * Truncate the job. print_job_end will take
                 * care of deleting it for us. JRA.
                 */
-               sys_ftruncate(fsp->fd, 0);
+               sys_ftruncate(fsp->fh->fd, 0);
        }
 
-       print_job_end(fsp->print_jobid, normal_close);
-
        if (fsp->fsp_name) {
                string_free(&fsp->fsp_name);
        }
+
+       if (!rap_to_pjobid(fsp->rap_print_jobid, sharename, &jobid)) {
+               DEBUG(3,("print_fsp_end: Unable to convert RAP jobid %u to print jobid.\n",
+                       (unsigned int)fsp->rap_print_jobid ));
+               return;
+       }
+
+       print_job_end(SNUM(fsp->conn),jobid, close_type);
 }