mirror of
https://github.com/samba-team/samba.git
synced 2025-01-13 13:18:06 +03:00
added support for printing via smbwrapper
You can print using "cp filename /smb/SERVER/PRINTER/jobname" You can list the current printqueue using ls
This commit is contained in:
parent
c5210cb0ff
commit
080fb61b69
@ -25,8 +25,9 @@
|
||||
#define _CLIENT_H
|
||||
|
||||
/* the client asks for a smaller buffer to save ram and also to get more
|
||||
overlap on the wire */
|
||||
#define CLI_BUFFER_SIZE (0x4000)
|
||||
overlap on the wire. This size gives us a nice read/write size, which
|
||||
will be a multiple of the page size on almost any system */
|
||||
#define CLI_BUFFER_SIZE (0x4400)
|
||||
|
||||
/*
|
||||
* These definitions depend on smb.h
|
||||
@ -45,6 +46,16 @@ typedef struct file_info
|
||||
pstring name;
|
||||
} file_info;
|
||||
|
||||
struct print_job_info
|
||||
{
|
||||
uint16 id;
|
||||
uint16 priority;
|
||||
size_t size;
|
||||
fstring user;
|
||||
fstring name;
|
||||
time_t t;
|
||||
};
|
||||
|
||||
struct pwd_info
|
||||
{
|
||||
BOOL null_pwd;
|
||||
|
@ -321,6 +321,7 @@ struct hostent *Get_Hostbyname(char *name);
|
||||
BOOL process_exists(int pid);
|
||||
char *uidtoname(uid_t uid);
|
||||
char *gidtoname(gid_t gid);
|
||||
uid_t nametouid(const char *name);
|
||||
void smb_panic(char *why);
|
||||
char *readdirname(void *p);
|
||||
BOOL is_in_path(char *name, name_compare_entry *namelist);
|
||||
@ -417,6 +418,8 @@ BOOL cli_establish_connection(struct cli_state *cli,
|
||||
struct nmb_name *calling, struct nmb_name *called,
|
||||
char *service, char *service_type,
|
||||
BOOL do_shutdown, BOOL do_tcon);
|
||||
int cli_print_queue(struct cli_state *cli,
|
||||
void (*fn)(struct print_job_info *));
|
||||
|
||||
/*The following definitions come from libsmb/credentials.c */
|
||||
|
||||
@ -2294,6 +2297,8 @@ int smbw_utime(const char *fname, void *buf);
|
||||
int smbw_chown(const char *fname, uid_t owner, gid_t group);
|
||||
int smbw_chmod(const char *fname, mode_t newmode);
|
||||
off_t smbw_lseek(int fd, off_t offset, int whence);
|
||||
int smbw_dup(int fd);
|
||||
int smbw_dup2(int fd, int fd2);
|
||||
|
||||
/*The following definitions come from smbwrapper/smbw_dir.c */
|
||||
|
||||
@ -2321,6 +2326,8 @@ void smbw_setup_stat(struct stat *st, char *fname, size_t size, int mode);
|
||||
BOOL smbw_getatr(struct smbw_server *srv, char *path,
|
||||
uint32 *mode, size_t *size,
|
||||
time_t *c_time, time_t *a_time, time_t *m_time);
|
||||
int smbw_stat_printjob(struct smbw_server *srv,char *path,
|
||||
size_t *size, time_t *m_time);
|
||||
int smbw_fstat(int fd, struct stat *st);
|
||||
int smbw_stat(const char *fname, struct stat *st);
|
||||
|
||||
|
@ -4044,7 +4044,6 @@ BOOL process_exists(int pid)
|
||||
/*******************************************************************
|
||||
turn a uid into a user name
|
||||
********************************************************************/
|
||||
|
||||
char *uidtoname(uid_t uid)
|
||||
{
|
||||
static char name[40];
|
||||
@ -4054,6 +4053,7 @@ char *uidtoname(uid_t uid)
|
||||
return(name);
|
||||
}
|
||||
|
||||
|
||||
/*******************************************************************
|
||||
turn a gid into a group name
|
||||
********************************************************************/
|
||||
@ -4067,6 +4067,16 @@ char *gidtoname(gid_t gid)
|
||||
return(name);
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
turn a user name into a uid
|
||||
********************************************************************/
|
||||
uid_t nametouid(const char *name)
|
||||
{
|
||||
struct passwd *pass = getpwnam(name);
|
||||
if (pass) return(pass->pw_uid);
|
||||
return (uid_t)-1;
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
something really nasty happened - panic!
|
||||
********************************************************************/
|
||||
|
@ -137,6 +137,29 @@ static void cli_setup_packet(struct cli_state *cli)
|
||||
}
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
Convert a character pointer in a cli_call_api() response to a form we can use.
|
||||
This function contains code to prevent core dumps if the server returns
|
||||
invalid data.
|
||||
*****************************************************************************/
|
||||
static char *fix_char_ptr(unsigned int datap, unsigned int converter,
|
||||
char *rdata, int rdrcnt)
|
||||
{
|
||||
if (datap == 0) { /* turn NULL pointers into zero length strings */
|
||||
return "";
|
||||
} else {
|
||||
unsigned int offset = datap - converter;
|
||||
|
||||
if (offset >= rdrcnt) {
|
||||
DEBUG(1,("bad char ptr: datap=%u, converter=%u rdrcnt=%d>",
|
||||
datap, converter, rdrcnt));
|
||||
return "<ERROR>";
|
||||
} else {
|
||||
return &rdata[offset];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
send a SMB trans or trans2 request
|
||||
****************************************************************************/
|
||||
@ -739,6 +762,8 @@ BOOL cli_send_tconX(struct cli_state *cli,
|
||||
bzero(cli->outbuf,smb_size);
|
||||
bzero(cli->inbuf,smb_size);
|
||||
|
||||
fstrcpy(cli->share, share);
|
||||
|
||||
if (cli->sec_mode & 1) {
|
||||
passlen = 1;
|
||||
pass = "";
|
||||
@ -779,6 +804,8 @@ BOOL cli_send_tconX(struct cli_state *cli,
|
||||
return False;
|
||||
}
|
||||
|
||||
fstrcpy(cli->dev, smb_buf(cli->inbuf));
|
||||
|
||||
if (cli->protocol >= PROTOCOL_NT1 &&
|
||||
smb_buflen(cli->inbuf) == 3) {
|
||||
/* almost certainly win95 - enable bug fixes */
|
||||
@ -2466,3 +2493,76 @@ BOOL cli_establish_connection(struct cli_state *cli,
|
||||
|
||||
return True;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
call fn() on each entry in a print queue
|
||||
****************************************************************************/
|
||||
int cli_print_queue(struct cli_state *cli,
|
||||
void (*fn)(struct print_job_info *))
|
||||
{
|
||||
char *rparam = NULL;
|
||||
char *rdata = NULL;
|
||||
char *p;
|
||||
int rdrcnt, rprcnt;
|
||||
pstring param;
|
||||
int result_code=0;
|
||||
int i = -1;
|
||||
|
||||
bzero(param,sizeof(param));
|
||||
|
||||
p = param;
|
||||
SSVAL(p,0,76); /* API function number 76 (DosPrintJobEnum) */
|
||||
p += 2;
|
||||
pstrcpy(p,"zWrLeh"); /* parameter description? */
|
||||
p = skip_string(p,1);
|
||||
pstrcpy(p,"WWzWWDDzz"); /* returned data format */
|
||||
p = skip_string(p,1);
|
||||
pstrcpy(p,cli->share); /* name of queue */
|
||||
p = skip_string(p,1);
|
||||
SSVAL(p,0,2); /* API function level 2, PRJINFO_2 data structure */
|
||||
SSVAL(p,2,1000); /* size of bytes of returned data buffer */
|
||||
p += 4;
|
||||
pstrcpy(p,""); /* subformat */
|
||||
p = skip_string(p,1);
|
||||
|
||||
DEBUG(4,("doing cli_print_queue for %s\n", cli->share));
|
||||
|
||||
if (cli_api(cli,
|
||||
param, PTR_DIFF(p,param), 1024, /* Param, length, maxlen */
|
||||
NULL, 0, CLI_BUFFER_SIZE, /* data, length, maxlen */
|
||||
&rparam, &rprcnt, /* return params, length */
|
||||
&rdata, &rdrcnt)) { /* return data, length */
|
||||
int converter;
|
||||
result_code = SVAL(rparam,0);
|
||||
converter = SVAL(rparam,2); /* conversion factor */
|
||||
|
||||
if (result_code == 0) {
|
||||
struct print_job_info job;
|
||||
|
||||
p = rdata;
|
||||
|
||||
for (i = 0; i < SVAL(rparam,4); ++i) {
|
||||
job.id = SVAL(p,0);
|
||||
job.priority = SVAL(p,2);
|
||||
fstrcpy(job.user,
|
||||
fix_char_ptr(SVAL(p,4), converter,
|
||||
rdata, rdrcnt));
|
||||
job.t = make_unix_date3(p + 12);
|
||||
job.size = IVAL(p,16);
|
||||
fstrcpy(job.name,fix_char_ptr(SVAL(p,24),
|
||||
converter,
|
||||
rdata, rdrcnt));
|
||||
fn(&job);
|
||||
p += 28;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* If any parameters or data were returned, free the storage. */
|
||||
if(rparam) free(rparam);
|
||||
if(rdata) free(rdata);
|
||||
|
||||
return i;
|
||||
}
|
||||
|
@ -249,7 +249,7 @@ static int call_trans2open(connection_struct *conn, char *inbuf, char *outbuf,
|
||||
|
||||
if (sys_fstat(fsp->fd_ptr->fd,&sbuf) != 0) {
|
||||
close_file(fsp,False);
|
||||
return(ERROR(ERRDOS,ERRnoaccess));
|
||||
return(UNIXERROR(ERRDOS,ERRnoaccess));
|
||||
}
|
||||
|
||||
size = sbuf.st_size;
|
||||
@ -681,7 +681,7 @@ static int call_trans2findfirst(connection_struct *conn,
|
||||
}
|
||||
#endif
|
||||
|
||||
return(ERROR(ERRDOS,ERRbadpath));
|
||||
return(UNIXERROR(ERRDOS,ERRbadpath));
|
||||
}
|
||||
|
||||
p = strrchr(directory,'/');
|
||||
@ -707,7 +707,7 @@ static int call_trans2findfirst(connection_struct *conn,
|
||||
|
||||
dptr_num = dptr_create(conn,directory, True ,SVAL(inbuf,smb_pid));
|
||||
if (dptr_num < 0)
|
||||
return(ERROR(ERRDOS,ERRbadfile));
|
||||
return(UNIXERROR(ERRDOS,ERRbadfile));
|
||||
|
||||
/* Convert the formatted mask. */
|
||||
mask_convert(mask);
|
||||
@ -1475,7 +1475,7 @@ static int call_trans2setfilepathinfo(connection_struct *conn,
|
||||
|
||||
if(sys_fstat(fd,&st)!=0) {
|
||||
DEBUG(3,("fstat of %s failed (%s)\n", fname, strerror(errno)));
|
||||
return(ERROR(ERRDOS,ERRbadpath));
|
||||
return(UNIXERROR(ERRDOS,ERRbadpath));
|
||||
}
|
||||
} else {
|
||||
/* set path info */
|
||||
@ -1639,7 +1639,7 @@ static int call_trans2setfilepathinfo(connection_struct *conn,
|
||||
{
|
||||
if(file_utime(conn, fname, &tvs)!=0)
|
||||
{
|
||||
return(ERROR(ERRDOS,ERRnoaccess));
|
||||
return(UNIXERROR(ERRDOS,ERRnoaccess));
|
||||
}
|
||||
}
|
||||
|
||||
@ -1647,7 +1647,7 @@ static int call_trans2setfilepathinfo(connection_struct *conn,
|
||||
if (mode != dos_mode(conn, fname, &st) && file_chmod(conn, fname, mode, NULL))
|
||||
{
|
||||
DEBUG(2,("chmod of %s failed (%s)\n", fname, strerror(errno)));
|
||||
return(ERROR(ERRDOS,ERRnoaccess));
|
||||
return(UNIXERROR(ERRDOS,ERRnoaccess));
|
||||
}
|
||||
|
||||
if(size != st.st_size)
|
||||
@ -1657,7 +1657,7 @@ static int call_trans2setfilepathinfo(connection_struct *conn,
|
||||
fd = dos_open(fname,O_RDWR,0);
|
||||
if (fd == -1)
|
||||
{
|
||||
return(ERROR(ERRDOS,ERRbadpath));
|
||||
return(UNIXERROR(ERRDOS,ERRbadpath));
|
||||
}
|
||||
set_filelen(fd, size);
|
||||
close(fd);
|
||||
|
@ -390,8 +390,7 @@ struct smbw_server *smbw_server(char *server, char *share)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!cli_send_tconX(&c, share,
|
||||
strstr(share,"IPC$")?"IPC":"A:",
|
||||
if (!cli_send_tconX(&c, share, "?????",
|
||||
password, strlen(password)+1)) {
|
||||
errno = smbw_errno(&c);
|
||||
cli_shutdown(&c);
|
||||
|
@ -112,6 +112,28 @@ static void smbw_share_add(const char *share, uint32 type, const char *comment)
|
||||
}
|
||||
|
||||
|
||||
/*****************************************************
|
||||
add a entry to a directory listing
|
||||
*******************************************************/
|
||||
static void smbw_printjob_add(struct print_job_info *job)
|
||||
{
|
||||
struct file_info finfo;
|
||||
|
||||
ZERO_STRUCT(finfo);
|
||||
|
||||
pstrcpy(finfo.name, job->name);
|
||||
finfo.mode = aRONLY | aDIR;
|
||||
finfo.mtime = job->t;
|
||||
finfo.atime = job->t;
|
||||
finfo.ctime = job->t;
|
||||
finfo.uid = nametouid(job->user);
|
||||
finfo.mode = aRONLY;
|
||||
finfo.size = job->size;
|
||||
|
||||
smbw_dir_add(&finfo);
|
||||
}
|
||||
|
||||
|
||||
/*****************************************************
|
||||
open a directory on the server
|
||||
*******************************************************/
|
||||
@ -159,15 +181,20 @@ int smbw_dir_open(const char *fname)
|
||||
slprintf(mask, sizeof(mask)-1, "%s\\*", path);
|
||||
string_sub(mask,"\\\\","\\");
|
||||
|
||||
if (strcmp(share,"IPC$") == 0) {
|
||||
if (strcmp(srv->cli.dev,"IPC") == 0) {
|
||||
DEBUG(4,("doing NetShareEnum\n"));
|
||||
if (cli_RNetShareEnum(&srv->cli, smbw_share_add) <= 0) {
|
||||
if (cli_RNetShareEnum(&srv->cli, smbw_share_add) < 0) {
|
||||
errno = smbw_errno(&srv->cli);
|
||||
goto failed;
|
||||
}
|
||||
} else if (strncmp(srv->cli.dev,"LPT",3) == 0) {
|
||||
if (cli_print_queue(&srv->cli, smbw_printjob_add) < 0) {
|
||||
errno = smbw_errno(&srv->cli);
|
||||
goto failed;
|
||||
}
|
||||
} else {
|
||||
if (cli_list(&srv->cli, mask, aHIDDEN|aSYSTEM|aDIR,
|
||||
smbw_dir_add) <= 0) {
|
||||
smbw_dir_add) < 0) {
|
||||
errno = smbw_errno(&srv->cli);
|
||||
goto failed;
|
||||
}
|
||||
@ -344,7 +371,8 @@ int smbw_chdir(const char *name)
|
||||
goto failed;
|
||||
}
|
||||
|
||||
if (strcmp(share,"IPC$") &&
|
||||
if (strncmp(srv->cli.dev,"IPC",3) &&
|
||||
strncmp(srv->cli.dev,"LPT",3) &&
|
||||
!smbw_getatr(srv, path,
|
||||
&mode, NULL, NULL, NULL, NULL)) {
|
||||
errno = smbw_errno(&srv->cli);
|
||||
|
@ -74,6 +74,38 @@ BOOL smbw_getatr(struct smbw_server *srv, char *path,
|
||||
return False;
|
||||
}
|
||||
|
||||
|
||||
static struct print_job_info printjob;
|
||||
|
||||
/*****************************************************
|
||||
gather info from a printjob listing
|
||||
*******************************************************/
|
||||
static void smbw_printjob_stat(struct print_job_info *job)
|
||||
{
|
||||
if (strcmp(job->name, printjob.name) == 0) {
|
||||
printjob = *job;
|
||||
}
|
||||
}
|
||||
|
||||
/*****************************************************
|
||||
stat a printjob
|
||||
*******************************************************/
|
||||
int smbw_stat_printjob(struct smbw_server *srv,char *path,
|
||||
size_t *size, time_t *m_time)
|
||||
{
|
||||
if (path[0] == '\\') path++;
|
||||
|
||||
ZERO_STRUCT(printjob);
|
||||
|
||||
fstrcpy(printjob.name, path);
|
||||
cli_print_queue(&srv->cli, smbw_printjob_stat);
|
||||
|
||||
*size = printjob.size;
|
||||
*m_time = printjob.t;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*****************************************************
|
||||
a wrapper for fstat()
|
||||
*******************************************************/
|
||||
@ -151,8 +183,16 @@ int smbw_stat(const char *fname, struct stat *st)
|
||||
goto failed;
|
||||
}
|
||||
|
||||
if (strcmp(share,"IPC$") == 0) {
|
||||
if (strncmp(srv->cli.dev,"IPC",3) == 0) {
|
||||
mode = aDIR | aRONLY;
|
||||
} else if (strncmp(srv->cli.dev,"LPT",3) == 0) {
|
||||
if (strcmp(path,"\\") == 0) {
|
||||
mode = aDIR | aRONLY;
|
||||
} else {
|
||||
mode = aRONLY;
|
||||
smbw_stat_printjob(srv, path, &size, &m_time);
|
||||
c_time = a_time = m_time;
|
||||
}
|
||||
} else {
|
||||
if (!smbw_getatr(srv, path,
|
||||
&mode, &size, &c_time, &a_time, &m_time)) {
|
||||
@ -163,8 +203,8 @@ int smbw_stat(const char *fname, struct stat *st)
|
||||
|
||||
smbw_setup_stat(st, path, size, mode);
|
||||
|
||||
st->st_atime = time(NULL);
|
||||
st->st_ctime = m_time;
|
||||
st->st_atime = a_time;
|
||||
st->st_ctime = c_time;
|
||||
st->st_mtime = m_time;
|
||||
st->st_dev = srv->dev;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user