mirror of
https://github.com/samba-team/samba.git
synced 2024-12-25 23:21:54 +03:00
the changes to the main smb code
------------ The following series of commits are for the new tdb based printing backend. This completely replaces our old printing backend. Major changes include: - all print ops are now done in printing/*.c rather than scattered all over the place - system job ids are decoupled from SMB job ids - the lpq parsers don't need to be nearly so smart, they only need to parse the filename, the status and system job id - we can store lots more info about a job, including the full job name - the queue cache control is much better I also added a new utility routine file_lines_load() that loads a text file and parses it into lines. This is used in out lpq parsing and I also want to use it to replace all of our fgets() based code in other places.
This commit is contained in:
parent
2df82862c0
commit
d870542c28
@ -100,6 +100,12 @@ static int close_normal_file(files_struct *fsp, BOOL normal_close)
|
|||||||
|
|
||||||
close_filestruct(fsp);
|
close_filestruct(fsp);
|
||||||
|
|
||||||
|
if (normal_close && fsp->print_file) {
|
||||||
|
print_fsp_end(fsp);
|
||||||
|
file_free(fsp);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
if (lp_share_modes(SNUM(conn))) {
|
if (lp_share_modes(SNUM(conn))) {
|
||||||
lock_share_entry_fsp(fsp);
|
lock_share_entry_fsp(fsp);
|
||||||
del_share_mode(fsp);
|
del_share_mode(fsp);
|
||||||
@ -115,10 +121,6 @@ static int close_normal_file(files_struct *fsp, BOOL normal_close)
|
|||||||
|
|
||||||
err = fd_close(conn, fsp);
|
err = fd_close(conn, fsp);
|
||||||
|
|
||||||
/* NT uses smbclose to start a print - weird */
|
|
||||||
if (normal_close && fsp->print_file)
|
|
||||||
print_file(conn, fsp);
|
|
||||||
|
|
||||||
/* check for magic scripts */
|
/* check for magic scripts */
|
||||||
if (normal_close) {
|
if (normal_close) {
|
||||||
check_magic(fsp,conn);
|
check_magic(fsp,conn);
|
||||||
|
@ -96,6 +96,11 @@ ssize_t read_file(files_struct *fsp,char *data,SMB_OFF_T pos,size_t n)
|
|||||||
{
|
{
|
||||||
ssize_t ret=0,readret;
|
ssize_t ret=0,readret;
|
||||||
|
|
||||||
|
/* you can't read from print files */
|
||||||
|
if (fsp->print_file) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Serve from write cache if we can.
|
* Serve from write cache if we can.
|
||||||
*/
|
*/
|
||||||
@ -154,6 +159,10 @@ ssize_t write_file(files_struct *fsp, char *data, SMB_OFF_T pos, size_t n)
|
|||||||
ssize_t total_written = 0;
|
ssize_t total_written = 0;
|
||||||
int write_path = -1;
|
int write_path = -1;
|
||||||
|
|
||||||
|
if (fsp->print_file) {
|
||||||
|
return print_job_write(fsp->print_jobid, data, n);
|
||||||
|
}
|
||||||
|
|
||||||
if (!fsp->can_write) {
|
if (!fsp->can_write) {
|
||||||
errno = EPERM;
|
errno = EPERM;
|
||||||
return(0);
|
return(0);
|
||||||
|
@ -290,6 +290,9 @@ static int getlen(char* p)
|
|||||||
case 'W': /* word (2 byte) */
|
case 'W': /* word (2 byte) */
|
||||||
n += 2;
|
n += 2;
|
||||||
break;
|
break;
|
||||||
|
case 'K': /* status word? (2 byte) */
|
||||||
|
n += 2;
|
||||||
|
break;
|
||||||
case 'N': /* count of substructures (word) at end */
|
case 'N': /* count of substructures (word) at end */
|
||||||
n += 2;
|
n += 2;
|
||||||
break;
|
break;
|
||||||
@ -385,6 +388,11 @@ va_dcl
|
|||||||
temp = va_arg(args,int);
|
temp = va_arg(args,int);
|
||||||
if (p->buflen >= needed) SSVAL(p->structbuf,0,temp);
|
if (p->buflen >= needed) SSVAL(p->structbuf,0,temp);
|
||||||
break;
|
break;
|
||||||
|
case 'K': /* status word? (2 byte) */
|
||||||
|
needed = 2;
|
||||||
|
temp = va_arg(args,int);
|
||||||
|
if (p->buflen >= needed) SSVAL(p->structbuf,0,temp);
|
||||||
|
break;
|
||||||
case 'N': /* count of substructures (word) at end */
|
case 'N': /* count of substructures (word) at end */
|
||||||
needed = 2;
|
needed = 2;
|
||||||
p->subcount = va_arg(args,int);
|
p->subcount = va_arg(args,int);
|
||||||
@ -474,7 +482,6 @@ static void PACKS(struct pack_desc* desc,char *t,char *v)
|
|||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
get a print queue
|
get a print queue
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
static void PackDriverData(struct pack_desc* desc)
|
static void PackDriverData(struct pack_desc* desc)
|
||||||
{
|
{
|
||||||
char drivdata[4+4+32];
|
char drivdata[4+4+32];
|
||||||
@ -510,6 +517,9 @@ static int check_printq_info(struct pack_desc* desc,
|
|||||||
case 5:
|
case 5:
|
||||||
desc->format = "z";
|
desc->format = "z";
|
||||||
break;
|
break;
|
||||||
|
case 51:
|
||||||
|
desc->format = "K";
|
||||||
|
break;
|
||||||
case 52:
|
case 52:
|
||||||
desc->format = "WzzzzzzzzN";
|
desc->format = "WzzzzzzzzN";
|
||||||
desc->subformat = "z";
|
desc->subformat = "z";
|
||||||
@ -530,7 +540,7 @@ static void fill_printjob_info(connection_struct *conn, int snum, int uLevel,
|
|||||||
/* the client expects localtime */
|
/* the client expects localtime */
|
||||||
t -= TimeDiff(t);
|
t -= TimeDiff(t);
|
||||||
|
|
||||||
PACKI(desc,"W",printjob_encode(snum, queue->job)); /* uJobId */
|
PACKI(desc,"W",queue->job); /* uJobId */
|
||||||
if (uLevel == 1) {
|
if (uLevel == 1) {
|
||||||
PACKS(desc,"B21",queue->user); /* szUserName */
|
PACKS(desc,"B21",queue->user); /* szUserName */
|
||||||
PACKS(desc,"B",""); /* pad */
|
PACKS(desc,"B",""); /* pad */
|
||||||
@ -568,171 +578,187 @@ static void fill_printjob_info(connection_struct *conn, int snum, int uLevel,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void fill_printq_info_52(connection_struct *conn, int snum, int uLevel,
|
||||||
|
struct pack_desc* desc,
|
||||||
|
int count, print_queue_struct* queue,
|
||||||
|
print_status_struct* status)
|
||||||
|
{
|
||||||
|
int i,ok=0;
|
||||||
|
pstring tok,driver,datafile,langmon,helpfile,datatype;
|
||||||
|
char *p,*q;
|
||||||
|
FILE *f;
|
||||||
|
pstring fname;
|
||||||
|
|
||||||
|
pstrcpy(fname,lp_driverfile());
|
||||||
|
f=sys_fopen(fname,"r");
|
||||||
|
if (!f) {
|
||||||
|
DEBUG(3,("fill_printq_info: Can't open %s - %s\n",fname,strerror(errno)));
|
||||||
|
desc->errcode=NERR_notsupported;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if((p=(char *)malloc(8192*sizeof(char))) == NULL) {
|
||||||
|
DEBUG(0,("fill_printq_info: malloc fail !\n"));
|
||||||
|
desc->errcode=NERR_notsupported;
|
||||||
|
fclose(f);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
memset(p, '\0',8192*sizeof(char));
|
||||||
|
q=p;
|
||||||
|
|
||||||
|
/* lookup the long printer driver name in the file
|
||||||
|
description */
|
||||||
|
while (f && !feof(f) && !ok) {
|
||||||
|
p = q; /* reset string pointer */
|
||||||
|
fgets(p,8191,f);
|
||||||
|
p[strlen(p)-1]='\0';
|
||||||
|
if (next_token(&p,tok,":",sizeof(tok)) &&
|
||||||
|
(strlen(lp_printerdriver(snum)) == strlen(tok)) &&
|
||||||
|
(!strncmp(tok,lp_printerdriver(snum),strlen(lp_printerdriver(snum)))))
|
||||||
|
ok=1;
|
||||||
|
}
|
||||||
|
fclose(f);
|
||||||
|
|
||||||
|
/* driver file name */
|
||||||
|
if (ok && !next_token(&p,driver,":",sizeof(driver))) ok = 0;
|
||||||
|
/* data file name */
|
||||||
|
if (ok && !next_token(&p,datafile,":",sizeof(datafile))) ok = 0;
|
||||||
|
/*
|
||||||
|
* for the next tokens - which may be empty - I have
|
||||||
|
* to check for empty tokens first because the
|
||||||
|
* next_token function will skip all empty token
|
||||||
|
* fields */
|
||||||
|
if (ok) {
|
||||||
|
/* help file */
|
||||||
|
if (*p == ':') {
|
||||||
|
*helpfile = '\0';
|
||||||
|
p++;
|
||||||
|
} else if (!next_token(&p,helpfile,":",sizeof(helpfile))) ok = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ok) {
|
||||||
|
/* language monitor */
|
||||||
|
if (*p == ':') {
|
||||||
|
*langmon = '\0';
|
||||||
|
p++;
|
||||||
|
} else if (!next_token(&p,langmon,":",sizeof(langmon)))
|
||||||
|
ok = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* default data type */
|
||||||
|
if (ok && !next_token(&p,datatype,":",sizeof(datatype)))
|
||||||
|
ok = 0;
|
||||||
|
|
||||||
|
if (ok) {
|
||||||
|
PACKI(desc,"W",0x0400); /* don't know */
|
||||||
|
PACKS(desc,"z",lp_printerdriver(snum)); /* long printer name */
|
||||||
|
PACKS(desc,"z",driver); /* Driverfile Name */
|
||||||
|
PACKS(desc,"z",datafile); /* Datafile name */
|
||||||
|
PACKS(desc,"z",langmon); /* language monitor */
|
||||||
|
PACKS(desc,"z",lp_driverlocation(snum)); /* share to retrieve files */
|
||||||
|
PACKS(desc,"z",datatype); /* default data type */
|
||||||
|
PACKS(desc,"z",helpfile); /* helpfile name */
|
||||||
|
PACKS(desc,"z",driver); /* driver name */
|
||||||
|
DEBUG(3,("Driver:%s:\n",driver));
|
||||||
|
DEBUG(3,("Data File:%s:\n",datafile));
|
||||||
|
DEBUG(3,("Language Monitor:%s:\n",langmon));
|
||||||
|
DEBUG(3,("Data Type:%s:\n",datatype));
|
||||||
|
DEBUG(3,("Help File:%s:\n",helpfile));
|
||||||
|
PACKI(desc,"N",count); /* number of files to copy */
|
||||||
|
for (i=0;i<count;i++) {
|
||||||
|
/* no need to check return value here
|
||||||
|
* - it was already tested in
|
||||||
|
* get_printerdrivernumber */
|
||||||
|
next_token(&p,tok,",",sizeof(tok));
|
||||||
|
PACKS(desc,"z",tok); /* driver files to copy */
|
||||||
|
DEBUG(3,("file:%s:\n",tok));
|
||||||
|
}
|
||||||
|
|
||||||
|
DEBUG(3,("fill_printq_info on <%s> gave %d entries\n",
|
||||||
|
SERVICE(snum),count));
|
||||||
|
} else {
|
||||||
|
DEBUG(3,("fill_printq_info: Can't supply driver files\n"));
|
||||||
|
desc->errcode=NERR_notsupported;
|
||||||
|
}
|
||||||
|
free(q);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static void fill_printq_info(connection_struct *conn, int snum, int uLevel,
|
static void fill_printq_info(connection_struct *conn, int snum, int uLevel,
|
||||||
struct pack_desc* desc,
|
struct pack_desc* desc,
|
||||||
int count, print_queue_struct* queue,
|
int count, print_queue_struct* queue,
|
||||||
print_status_struct* status)
|
print_status_struct* status)
|
||||||
{
|
{
|
||||||
switch (uLevel) {
|
switch (uLevel) {
|
||||||
case 1:
|
case 1:
|
||||||
case 2:
|
case 2:
|
||||||
PACKS(desc,"B13",SERVICE(snum));
|
PACKS(desc,"B13",SERVICE(snum));
|
||||||
break;
|
break;
|
||||||
case 3:
|
case 3:
|
||||||
case 4:
|
case 4:
|
||||||
case 5:
|
case 5:
|
||||||
PACKS(desc,"z",Expand(conn,snum,SERVICE(snum)));
|
PACKS(desc,"z",Expand(conn,snum,SERVICE(snum)));
|
||||||
break;
|
break;
|
||||||
}
|
case 51:
|
||||||
|
PACKI(desc,"K",status->status);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
if (uLevel == 1 || uLevel == 2) {
|
if (uLevel == 1 || uLevel == 2) {
|
||||||
PACKS(desc,"B",""); /* alignment */
|
PACKS(desc,"B",""); /* alignment */
|
||||||
PACKI(desc,"W",5); /* priority */
|
PACKI(desc,"W",5); /* priority */
|
||||||
PACKI(desc,"W",0); /* start time */
|
PACKI(desc,"W",0); /* start time */
|
||||||
PACKI(desc,"W",0); /* until time */
|
PACKI(desc,"W",0); /* until time */
|
||||||
PACKS(desc,"z",""); /* pSepFile */
|
PACKS(desc,"z",""); /* pSepFile */
|
||||||
PACKS(desc,"z","lpd"); /* pPrProc */
|
PACKS(desc,"z","lpd"); /* pPrProc */
|
||||||
PACKS(desc,"z",SERVICE(snum)); /* pDestinations */
|
PACKS(desc,"z",SERVICE(snum)); /* pDestinations */
|
||||||
PACKS(desc,"z",""); /* pParms */
|
PACKS(desc,"z",""); /* pParms */
|
||||||
if (snum < 0) {
|
if (snum < 0) {
|
||||||
PACKS(desc,"z","UNKNOWN PRINTER");
|
PACKS(desc,"z","UNKNOWN PRINTER");
|
||||||
PACKI(desc,"W",LPSTAT_ERROR);
|
PACKI(desc,"W",LPSTAT_ERROR);
|
||||||
}
|
}
|
||||||
else if (!status || !status->message[0]) {
|
else if (!status || !status->message[0]) {
|
||||||
PACKS(desc,"z",Expand(conn,snum,lp_comment(snum)));
|
PACKS(desc,"z",Expand(conn,snum,lp_comment(snum)));
|
||||||
PACKI(desc,"W",LPSTAT_OK); /* status */
|
PACKI(desc,"W",LPSTAT_OK); /* status */
|
||||||
} else {
|
} else {
|
||||||
PACKS(desc,"z",status->message);
|
PACKS(desc,"z",status->message);
|
||||||
PACKI(desc,"W",status->status); /* status */
|
PACKI(desc,"W",status->status); /* status */
|
||||||
}
|
}
|
||||||
PACKI(desc,(uLevel == 1 ? "W" : "N"),count);
|
PACKI(desc,(uLevel == 1 ? "W" : "N"),count);
|
||||||
}
|
}
|
||||||
if (uLevel == 3 || uLevel == 4) {
|
|
||||||
PACKI(desc,"W",5); /* uPriority */
|
|
||||||
PACKI(desc,"W",0); /* uStarttime */
|
|
||||||
PACKI(desc,"W",0); /* uUntiltime */
|
|
||||||
PACKI(desc,"W",5); /* pad1 */
|
|
||||||
PACKS(desc,"z",""); /* pszSepFile */
|
|
||||||
PACKS(desc,"z","WinPrint"); /* pszPrProc */
|
|
||||||
PACKS(desc,"z",""); /* pszParms */
|
|
||||||
if (!status || !status->message[0]) {
|
|
||||||
PACKS(desc,"z",Expand(conn,snum,lp_comment(snum))); /* pszComment */
|
|
||||||
PACKI(desc,"W",LPSTAT_OK); /* fsStatus */
|
|
||||||
} else {
|
|
||||||
PACKS(desc,"z",status->message); /* pszComment */
|
|
||||||
PACKI(desc,"W",status->status); /* fsStatus */
|
|
||||||
}
|
|
||||||
PACKI(desc,(uLevel == 3 ? "W" : "N"),count); /* cJobs */
|
|
||||||
PACKS(desc,"z",SERVICE(snum)); /* pszPrinters */
|
|
||||||
PACKS(desc,"z",lp_printerdriver(snum)); /* pszDriverName */
|
|
||||||
PackDriverData(desc); /* pDriverData */
|
|
||||||
}
|
|
||||||
if (uLevel == 2 || uLevel == 4) {
|
|
||||||
int i;
|
|
||||||
for (i=0;i<count;i++)
|
|
||||||
fill_printjob_info(conn,snum,uLevel == 2 ? 1 : 2,desc,&queue[i],i);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (uLevel==52) {
|
if (uLevel == 3 || uLevel == 4) {
|
||||||
int i,ok=0;
|
PACKI(desc,"W",5); /* uPriority */
|
||||||
pstring tok,driver,datafile,langmon,helpfile,datatype;
|
PACKI(desc,"W",0); /* uStarttime */
|
||||||
char *p,*q;
|
PACKI(desc,"W",0); /* uUntiltime */
|
||||||
FILE *f;
|
PACKI(desc,"W",5); /* pad1 */
|
||||||
pstring fname;
|
PACKS(desc,"z",""); /* pszSepFile */
|
||||||
|
PACKS(desc,"z","WinPrint"); /* pszPrProc */
|
||||||
|
PACKS(desc,"z",""); /* pszParms */
|
||||||
|
if (!status || !status->message[0]) {
|
||||||
|
PACKS(desc,"z",Expand(conn,snum,lp_comment(snum))); /* pszComment */
|
||||||
|
PACKI(desc,"W",LPSTAT_OK); /* fsStatus */
|
||||||
|
} else {
|
||||||
|
PACKS(desc,"z",status->message); /* pszComment */
|
||||||
|
PACKI(desc,"W",status->status); /* fsStatus */
|
||||||
|
}
|
||||||
|
PACKI(desc,(uLevel == 3 ? "W" : "N"),count); /* cJobs */
|
||||||
|
PACKS(desc,"z",SERVICE(snum)); /* pszPrinters */
|
||||||
|
PACKS(desc,"z",lp_printerdriver(snum)); /* pszDriverName */
|
||||||
|
PackDriverData(desc); /* pDriverData */
|
||||||
|
}
|
||||||
|
|
||||||
pstrcpy(fname,lp_driverfile());
|
if (uLevel == 2 || uLevel == 4) {
|
||||||
f=sys_fopen(fname,"r");
|
int i;
|
||||||
if (!f) {
|
for (i=0;i<count;i++)
|
||||||
DEBUG(3,("fill_printq_info: Can't open %s - %s\n",fname,strerror(errno)));
|
fill_printjob_info(conn,snum,uLevel == 2 ? 1 : 2,desc,&queue[i],i);
|
||||||
desc->errcode=NERR_notsupported;
|
}
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if((p=(char *)malloc(8192*sizeof(char))) == NULL) {
|
if (uLevel==52) {
|
||||||
DEBUG(0,("fill_printq_info: malloc fail !\n"));
|
fill_printq_info_52(conn, snum, uLevel, desc, count, queue, status);
|
||||||
desc->errcode=NERR_notsupported;
|
}
|
||||||
fclose(f);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
memset(p, '\0',8192*sizeof(char));
|
|
||||||
q=p;
|
|
||||||
|
|
||||||
/* lookup the long printer driver name in the file description */
|
|
||||||
while (f && !feof(f) && !ok)
|
|
||||||
{
|
|
||||||
p = q; /* reset string pointer */
|
|
||||||
fgets(p,8191,f);
|
|
||||||
p[strlen(p)-1]='\0';
|
|
||||||
if (next_token(&p,tok,":",sizeof(tok)) &&
|
|
||||||
(strlen(lp_printerdriver(snum)) == strlen(tok)) &&
|
|
||||||
(!strncmp(tok,lp_printerdriver(snum),strlen(lp_printerdriver(snum)))))
|
|
||||||
ok=1;
|
|
||||||
}
|
|
||||||
fclose(f);
|
|
||||||
|
|
||||||
/* driver file name */
|
|
||||||
if (ok && !next_token(&p,driver,":",sizeof(driver))) ok = 0;
|
|
||||||
/* data file name */
|
|
||||||
if (ok && !next_token(&p,datafile,":",sizeof(datafile))) ok = 0;
|
|
||||||
/*
|
|
||||||
* for the next tokens - which may be empty - I have to check for empty
|
|
||||||
* tokens first because the next_token function will skip all empty
|
|
||||||
* token fields
|
|
||||||
*/
|
|
||||||
if (ok) {
|
|
||||||
/* help file */
|
|
||||||
if (*p == ':') {
|
|
||||||
*helpfile = '\0';
|
|
||||||
p++;
|
|
||||||
} else if (!next_token(&p,helpfile,":",sizeof(helpfile))) ok = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ok) {
|
|
||||||
/* language monitor */
|
|
||||||
if (*p == ':') {
|
|
||||||
*langmon = '\0';
|
|
||||||
p++;
|
|
||||||
} else if (!next_token(&p,langmon,":",sizeof(langmon))) ok = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* default data type */
|
|
||||||
if (ok && !next_token(&p,datatype,":",sizeof(datatype))) ok = 0;
|
|
||||||
|
|
||||||
if (ok) {
|
|
||||||
PACKI(desc,"W",0x0400); /* don't know */
|
|
||||||
PACKS(desc,"z",lp_printerdriver(snum)); /* long printer name */
|
|
||||||
PACKS(desc,"z",driver); /* Driverfile Name */
|
|
||||||
PACKS(desc,"z",datafile); /* Datafile name */
|
|
||||||
PACKS(desc,"z",langmon); /* language monitor */
|
|
||||||
PACKS(desc,"z",lp_driverlocation(snum)); /* share to retrieve files */
|
|
||||||
PACKS(desc,"z",datatype); /* default data type */
|
|
||||||
PACKS(desc,"z",helpfile); /* helpfile name */
|
|
||||||
PACKS(desc,"z",driver); /* driver name */
|
|
||||||
DEBUG(3,("Driver:%s:\n",driver));
|
|
||||||
DEBUG(3,("Data File:%s:\n",datafile));
|
|
||||||
DEBUG(3,("Language Monitor:%s:\n",langmon));
|
|
||||||
DEBUG(3,("Data Type:%s:\n",datatype));
|
|
||||||
DEBUG(3,("Help File:%s:\n",helpfile));
|
|
||||||
PACKI(desc,"N",count); /* number of files to copy */
|
|
||||||
for (i=0;i<count;i++)
|
|
||||||
{
|
|
||||||
/* no need to check return value here - it was already tested in
|
|
||||||
* get_printerdrivernumber
|
|
||||||
*/
|
|
||||||
next_token(&p,tok,",",sizeof(tok));
|
|
||||||
PACKS(desc,"z",tok); /* driver files to copy */
|
|
||||||
DEBUG(3,("file:%s:\n",tok));
|
|
||||||
}
|
|
||||||
|
|
||||||
DEBUG(3,("fill_printq_info on <%s> gave %d entries\n",
|
|
||||||
SERVICE(snum),count));
|
|
||||||
} else {
|
|
||||||
DEBUG(3,("fill_printq_info: Can't supply driver files\n"));
|
|
||||||
desc->errcode=NERR_notsupported;
|
|
||||||
}
|
|
||||||
free(q);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* This function returns the number of files for a given driver */
|
/* This function returns the number of files for a given driver */
|
||||||
@ -852,7 +878,7 @@ static BOOL api_DosPrintQGetInfo(connection_struct *conn,
|
|||||||
count = get_printerdrivernumber(snum);
|
count = get_printerdrivernumber(snum);
|
||||||
DEBUG(3,("api_DosPrintQGetInfo: Driver files count: %d\n",count));
|
DEBUG(3,("api_DosPrintQGetInfo: Driver files count: %d\n",count));
|
||||||
} else {
|
} else {
|
||||||
count = get_printqueue(snum, conn,&queue,&status);
|
count = print_queue_status(snum, &queue,&status);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mdrcnt > 0) *rdata = REALLOC(*rdata,mdrcnt);
|
if (mdrcnt > 0) *rdata = REALLOC(*rdata,mdrcnt);
|
||||||
@ -963,7 +989,7 @@ static BOOL api_DosPrintQEnum(connection_struct *conn, uint16 vuid, char* param,
|
|||||||
n = 0;
|
n = 0;
|
||||||
for (i = 0; i < services; i++)
|
for (i = 0; i < services; i++)
|
||||||
if (lp_snum_ok(i) && lp_print_ok(i) && lp_browseable(i)) {
|
if (lp_snum_ok(i) && lp_print_ok(i) && lp_browseable(i)) {
|
||||||
subcntarr[n] = get_printqueue(i, conn,&queue[n],&status[n]);
|
subcntarr[n] = print_queue_status(i, &queue[n],&status[n]);
|
||||||
subcnt += subcntarr[n];
|
subcnt += subcntarr[n];
|
||||||
n++;
|
n++;
|
||||||
}
|
}
|
||||||
@ -1842,60 +1868,46 @@ static BOOL api_RDosPrintJobDel(connection_struct *conn,uint16 vuid, char *param
|
|||||||
char **rdata,char **rparam,
|
char **rdata,char **rparam,
|
||||||
int *rdata_len,int *rparam_len)
|
int *rdata_len,int *rparam_len)
|
||||||
{
|
{
|
||||||
int function = SVAL(param,0);
|
int function = SVAL(param,0);
|
||||||
char *str1 = param+2;
|
char *str1 = param+2;
|
||||||
char *str2 = skip_string(str1,1);
|
char *str2 = skip_string(str1,1);
|
||||||
char *p = skip_string(str2,1);
|
char *p = skip_string(str2,1);
|
||||||
int jobid, snum;
|
int jobid, errcode;
|
||||||
int i, count;
|
|
||||||
|
|
||||||
printjob_decode(SVAL(p,0), &snum, &jobid);
|
jobid = SVAL(p,0);
|
||||||
|
|
||||||
/* check it's a supported varient */
|
/* check it's a supported varient */
|
||||||
if (!(strcsequal(str1,"W") && strcsequal(str2,"")))
|
if (!(strcsequal(str1,"W") && strcsequal(str2,"")))
|
||||||
return(False);
|
return(False);
|
||||||
|
|
||||||
*rparam_len = 4;
|
*rparam_len = 4;
|
||||||
*rparam = REALLOC(*rparam,*rparam_len);
|
*rparam = REALLOC(*rparam,*rparam_len);
|
||||||
|
*rdata_len = 0;
|
||||||
|
|
||||||
*rdata_len = 0;
|
if (!print_job_exists(jobid)) {
|
||||||
|
errcode = NERR_JobNotFound;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
SSVAL(*rparam,0,NERR_Success);
|
errcode = NERR_notsupported;
|
||||||
|
|
||||||
|
switch (function) {
|
||||||
|
case 81: /* delete */
|
||||||
|
if (print_job_delete(jobid)) errcode = NERR_Success;
|
||||||
|
break;
|
||||||
|
case 82: /* pause */
|
||||||
|
if (print_job_pause(jobid)) errcode = NERR_Success;
|
||||||
|
break;
|
||||||
|
case 83: /* resume */
|
||||||
|
if (print_job_resume(jobid)) errcode = NERR_Success;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
out:
|
||||||
|
SSVAL(*rparam,0,errcode);
|
||||||
|
SSVAL(*rparam,2,0); /* converter word */
|
||||||
|
|
||||||
if (snum >= 0 && VALID_SNUM(snum))
|
return(True);
|
||||||
{
|
|
||||||
print_queue_struct *queue=NULL;
|
|
||||||
lpq_reset(snum);
|
|
||||||
count = get_printqueue(snum,conn,&queue,NULL);
|
|
||||||
|
|
||||||
for (i=0;i<count;i++)
|
|
||||||
if ((queue[i].job&0xFF) == jobid)
|
|
||||||
{
|
|
||||||
switch (function) {
|
|
||||||
case 81: /* delete */
|
|
||||||
DEBUG(3,("Deleting queue entry %d\n",queue[i].job));
|
|
||||||
del_printqueue(conn,snum,queue[i].job);
|
|
||||||
break;
|
|
||||||
case 82: /* pause */
|
|
||||||
case 83: /* resume */
|
|
||||||
DEBUG(3,("%s queue entry %d\n",
|
|
||||||
(function==82?"pausing":"resuming"),queue[i].job));
|
|
||||||
status_printjob(conn,snum,queue[i].job,
|
|
||||||
(function==82?LPQ_PAUSED:LPQ_QUEUED));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (i==count)
|
|
||||||
SSVAL(*rparam,0,NERR_JobNotFound);
|
|
||||||
|
|
||||||
if (queue) free(queue);
|
|
||||||
}
|
|
||||||
|
|
||||||
SSVAL(*rparam,2,0); /* converter word */
|
|
||||||
|
|
||||||
return(True);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
@ -1906,59 +1918,45 @@ static BOOL api_WPrintQueuePurge(connection_struct *conn,uint16 vuid, char *para
|
|||||||
char **rdata,char **rparam,
|
char **rdata,char **rparam,
|
||||||
int *rdata_len,int *rparam_len)
|
int *rdata_len,int *rparam_len)
|
||||||
{
|
{
|
||||||
int function = SVAL(param,0);
|
int function = SVAL(param,0);
|
||||||
char *str1 = param+2;
|
char *str1 = param+2;
|
||||||
char *str2 = skip_string(str1,1);
|
char *str2 = skip_string(str1,1);
|
||||||
char *QueueName = skip_string(str2,1);
|
char *QueueName = skip_string(str2,1);
|
||||||
int snum;
|
int errcode = NERR_notsupported;
|
||||||
|
int snum;
|
||||||
|
|
||||||
/* check it's a supported varient */
|
/* check it's a supported varient */
|
||||||
if (!(strcsequal(str1,"z") && strcsequal(str2,"")))
|
if (!(strcsequal(str1,"z") && strcsequal(str2,"")))
|
||||||
return(False);
|
return(False);
|
||||||
|
|
||||||
*rparam_len = 4;
|
*rparam_len = 4;
|
||||||
*rparam = REALLOC(*rparam,*rparam_len);
|
*rparam = REALLOC(*rparam,*rparam_len);
|
||||||
|
*rdata_len = 0;
|
||||||
|
|
||||||
*rdata_len = 0;
|
snum = print_queue_snum(QueueName);
|
||||||
|
|
||||||
SSVAL(*rparam,0,NERR_Success);
|
if (snum == -1) {
|
||||||
SSVAL(*rparam,2,0); /* converter word */
|
errcode = NERR_JobNotFound;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
snum = lp_servicenumber(QueueName);
|
switch (function) {
|
||||||
if (snum < 0 && pcap_printername_ok(QueueName,NULL)) {
|
case 74: /* Pause queue */
|
||||||
int pnum = lp_servicenumber(PRINTERS_NAME);
|
if (print_queue_pause(snum)) errcode = NERR_Success;
|
||||||
if (pnum >= 0) {
|
break;
|
||||||
lp_add_printer(QueueName,pnum);
|
case 75: /* Resume queue */
|
||||||
snum = lp_servicenumber(QueueName);
|
if (print_queue_resume(snum)) errcode = NERR_Success;
|
||||||
}
|
break;
|
||||||
}
|
case 103: /* Purge */
|
||||||
|
if (print_queue_purge(snum)) errcode = NERR_Success;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
if (snum >= 0 && VALID_SNUM(snum)) {
|
out:
|
||||||
lpq_reset(snum);
|
SSVAL(*rparam,0,errcode);
|
||||||
|
SSVAL(*rparam,2,0); /* converter word */
|
||||||
switch (function) {
|
|
||||||
case 74: /* Pause queue */
|
|
||||||
case 75: /* Resume queue */
|
|
||||||
status_printqueue(conn,snum,(function==74?LPSTAT_STOPPED:LPSTAT_OK));
|
|
||||||
DEBUG(3,("Print queue %s, queue=%s\n",
|
|
||||||
(function==74?"pause":"resume"),QueueName));
|
|
||||||
break;
|
|
||||||
case 103: /* Purge */
|
|
||||||
{
|
|
||||||
print_queue_struct *queue=NULL;
|
|
||||||
int i, count;
|
|
||||||
count = get_printqueue(snum,conn,&queue,NULL);
|
|
||||||
for (i = 0; i < count; i++)
|
|
||||||
del_printqueue(conn,snum,queue[i].job);
|
|
||||||
|
|
||||||
if (queue) free(queue);
|
|
||||||
DEBUG(3,("Print queue purge, queue=%s\n",QueueName));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return(True);
|
return(True);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -1972,16 +1970,16 @@ static BOOL api_WPrintQueuePurge(connection_struct *conn,uint16 vuid, char *para
|
|||||||
static int check_printjob_info(struct pack_desc* desc,
|
static int check_printjob_info(struct pack_desc* desc,
|
||||||
int uLevel, char* id)
|
int uLevel, char* id)
|
||||||
{
|
{
|
||||||
desc->subformat = NULL;
|
desc->subformat = NULL;
|
||||||
switch( uLevel ) {
|
switch( uLevel ) {
|
||||||
case 0: desc->format = "W"; break;
|
case 0: desc->format = "W"; break;
|
||||||
case 1: desc->format = "WB21BB16B10zWWzDDz"; break;
|
case 1: desc->format = "WB21BB16B10zWWzDDz"; break;
|
||||||
case 2: desc->format = "WWzWWDDzz"; break;
|
case 2: desc->format = "WWzWWDDzz"; break;
|
||||||
case 3: desc->format = "WWzWWDDzzzzzzzzzzlz"; break;
|
case 3: desc->format = "WWzWWDDzzzzzzzzzzlz"; break;
|
||||||
default: return False;
|
default: return False;
|
||||||
}
|
}
|
||||||
if (strcmp(desc->format,id) != 0) return False;
|
if (strcmp(desc->format,id) != 0) return False;
|
||||||
return True;
|
return True;
|
||||||
}
|
}
|
||||||
|
|
||||||
static BOOL api_PrintJobInfo(connection_struct *conn,uint16 vuid,char *param,char *data,
|
static BOOL api_PrintJobInfo(connection_struct *conn,uint16 vuid,char *param,char *data,
|
||||||
@ -1993,15 +1991,12 @@ static BOOL api_PrintJobInfo(connection_struct *conn,uint16 vuid,char *param,cha
|
|||||||
char *str1 = param+2;
|
char *str1 = param+2;
|
||||||
char *str2 = skip_string(str1,1);
|
char *str2 = skip_string(str1,1);
|
||||||
char *p = skip_string(str2,1);
|
char *p = skip_string(str2,1);
|
||||||
int jobid, snum;
|
int jobid;
|
||||||
int uLevel = SVAL(p,2);
|
int uLevel = SVAL(p,2);
|
||||||
int function = SVAL(p,4); /* what is this ?? */
|
int function = SVAL(p,4);
|
||||||
int i;
|
int place, errcode;
|
||||||
char *s = data;
|
|
||||||
files_struct *fsp;
|
|
||||||
|
|
||||||
printjob_decode(SVAL(p,0), &snum, &jobid);
|
jobid = SVAL(p,0);
|
||||||
|
|
||||||
*rparam_len = 4;
|
*rparam_len = 4;
|
||||||
*rparam = REALLOC(*rparam,*rparam_len);
|
*rparam = REALLOC(*rparam,*rparam_len);
|
||||||
|
|
||||||
@ -2011,87 +2006,37 @@ static BOOL api_PrintJobInfo(connection_struct *conn,uint16 vuid,char *param,cha
|
|||||||
if ((strcmp(str1,"WWsTP")) ||
|
if ((strcmp(str1,"WWsTP")) ||
|
||||||
(!check_printjob_info(&desc,uLevel,str2)))
|
(!check_printjob_info(&desc,uLevel,str2)))
|
||||||
return(False);
|
return(False);
|
||||||
|
|
||||||
|
if (!print_job_exists(jobid)) {
|
||||||
|
errcode=NERR_JobNotFound;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
errcode = NERR_notsupported;
|
||||||
|
|
||||||
switch (function) {
|
switch (function) {
|
||||||
case 0x6: /* change job place in the queue,
|
case 0x6:
|
||||||
data gives the new place */
|
/* change job place in the queue,
|
||||||
if (snum >= 0 && VALID_SNUM(snum)) {
|
data gives the new place */
|
||||||
print_queue_struct *queue=NULL;
|
place = SVAL(data,0);
|
||||||
int count;
|
if (print_job_set_place(jobid, place)) {
|
||||||
|
errcode=NERR_Success;
|
||||||
lpq_reset(snum);
|
|
||||||
count = get_printqueue(snum,conn,&queue,NULL);
|
|
||||||
for (i=0;i<count;i++) /* find job */
|
|
||||||
if ((queue[i].job&0xFF) == jobid) break;
|
|
||||||
|
|
||||||
if (i==count) {
|
|
||||||
desc.errcode=NERR_JobNotFound;
|
|
||||||
if (queue) free(queue);
|
|
||||||
} else {
|
|
||||||
desc.errcode=NERR_Success;
|
|
||||||
i++;
|
|
||||||
#if 0
|
|
||||||
{
|
|
||||||
int place= SVAL(data,0);
|
|
||||||
/* we currently have no way of
|
|
||||||
doing this. Can any unix do it? */
|
|
||||||
if (i < place) /* move down */;
|
|
||||||
else if (i > place ) /* move up */;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
desc.errcode=NERR_notsupported; /* not yet
|
|
||||||
supported */
|
|
||||||
if (queue) free(queue);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
desc.errcode=NERR_JobNotFound;
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0xb: /* change print job name, data gives the name */
|
case 0xb:
|
||||||
/* jobid, snum should be zero */
|
/* change print job name, data gives the name */
|
||||||
if (isalpha((int)*s)) {
|
if (print_job_set_name(jobid, data)) {
|
||||||
pstring name;
|
errcode=NERR_Success;
|
||||||
int l = 0;
|
|
||||||
|
|
||||||
while (l<64 && *s) {
|
|
||||||
if (issafe(*s)) name[l++] = *s;
|
|
||||||
s++;
|
|
||||||
}
|
|
||||||
name[l] = 0;
|
|
||||||
|
|
||||||
DEBUG(3,("Setting print name to %s\n",name));
|
|
||||||
|
|
||||||
fsp = file_find_print();
|
|
||||||
|
|
||||||
if (fsp) {
|
|
||||||
pstring zfrom,zto;
|
|
||||||
connection_struct *fconn = fsp->conn;
|
|
||||||
|
|
||||||
unbecome_user();
|
|
||||||
|
|
||||||
if (!become_user(fconn,vuid) ||
|
|
||||||
!become_service(fconn,True))
|
|
||||||
break;
|
|
||||||
|
|
||||||
pstrcpy(zfrom, dos_to_unix(fsp->fsp_name,False));
|
|
||||||
pstrcpy(zto, dos_to_unix(name,False));
|
|
||||||
|
|
||||||
if (fsp->conn->vfs_ops.rename(zfrom,zto) == 0) {
|
|
||||||
string_set(&fsp->fsp_name,name);
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
desc.errcode=NERR_Success;
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default: /* not implemented */
|
default:
|
||||||
return False;
|
return False;
|
||||||
}
|
}
|
||||||
|
|
||||||
SSVALS(*rparam,0,desc.errcode);
|
out:
|
||||||
|
SSVALS(*rparam,0,errcode);
|
||||||
SSVAL(*rparam,2,0); /* converter word */
|
SSVAL(*rparam,2,0); /* converter word */
|
||||||
|
|
||||||
return(True);
|
return(True);
|
||||||
@ -2793,13 +2738,13 @@ static BOOL api_WPrintJobGetInfo(connection_struct *conn,uint16 vuid, char *para
|
|||||||
if (strcmp(str1,"WWrLh") != 0) return False;
|
if (strcmp(str1,"WWrLh") != 0) return False;
|
||||||
if (!check_printjob_info(&desc,uLevel,str2)) return False;
|
if (!check_printjob_info(&desc,uLevel,str2)) return False;
|
||||||
|
|
||||||
printjob_decode(SVAL(p,0), &snum, &job);
|
job = SVAL(p,0);
|
||||||
|
|
||||||
if (snum < 0 || !VALID_SNUM(snum)) return(False);
|
if (snum < 0 || !VALID_SNUM(snum)) return(False);
|
||||||
|
|
||||||
count = get_printqueue(snum,conn,&queue,&status);
|
count = print_queue_status(snum,&queue,&status);
|
||||||
for (i = 0; i < count; i++) {
|
for (i = 0; i < count; i++) {
|
||||||
if ((queue[i].job & 0xFF) == job) break;
|
if (queue[i].job == job) break;
|
||||||
}
|
}
|
||||||
if (mdrcnt > 0) *rdata = REALLOC(*rdata,mdrcnt);
|
if (mdrcnt > 0) *rdata = REALLOC(*rdata,mdrcnt);
|
||||||
desc.base = *rdata;
|
desc.base = *rdata;
|
||||||
@ -2869,7 +2814,7 @@ static BOOL api_WPrintJobEnumerate(connection_struct *conn,uint16 vuid, char *pa
|
|||||||
|
|
||||||
if (snum < 0 || !VALID_SNUM(snum)) return(False);
|
if (snum < 0 || !VALID_SNUM(snum)) return(False);
|
||||||
|
|
||||||
count = get_printqueue(snum,conn,&queue,&status);
|
count = print_queue_status(snum,&queue,&status);
|
||||||
if (mdrcnt > 0) *rdata = REALLOC(*rdata,mdrcnt);
|
if (mdrcnt > 0) *rdata = REALLOC(*rdata,mdrcnt);
|
||||||
desc.base = *rdata;
|
desc.base = *rdata;
|
||||||
desc.buflen = mdrcnt;
|
desc.buflen = mdrcnt;
|
||||||
|
@ -413,7 +413,7 @@ void open_file_shared(files_struct *fsp,connection_struct *conn,char *fname,int
|
|||||||
ignored */
|
ignored */
|
||||||
*Access = DOS_OPEN_WRONLY;
|
*Access = DOS_OPEN_WRONLY;
|
||||||
*action = FILE_WAS_CREATED;
|
*action = FILE_WAS_CREATED;
|
||||||
print_open_file(fsp, conn, fname);
|
print_fsp_open(fsp, conn, fname);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -393,6 +393,7 @@ int reply_ioctl(connection_struct *conn,
|
|||||||
uint32 ioctl_code = (device << 16) + function;
|
uint32 ioctl_code = (device << 16) + function;
|
||||||
int replysize, outsize;
|
int replysize, outsize;
|
||||||
char *p;
|
char *p;
|
||||||
|
files_struct *fsp = file_fsp(inbuf,smb_vwv0);
|
||||||
|
|
||||||
DEBUG(4, ("Received IOCTL (code 0x%x)\n", ioctl_code));
|
DEBUG(4, ("Received IOCTL (code 0x%x)\n", ioctl_code));
|
||||||
|
|
||||||
@ -413,8 +414,8 @@ int reply_ioctl(connection_struct *conn,
|
|||||||
|
|
||||||
switch (ioctl_code)
|
switch (ioctl_code)
|
||||||
{
|
{
|
||||||
case IOCTL_QUERY_JOB_INFO:
|
case IOCTL_QUERY_JOB_INFO:
|
||||||
SSVAL(p,0,1); /* Job number */
|
SSVAL(p,0,fsp->print_jobid); /* Job number */
|
||||||
StrnCpy(p+2, global_myname, 15); /* Our NetBIOS name */
|
StrnCpy(p+2, global_myname, 15); /* Our NetBIOS name */
|
||||||
StrnCpy(p+18, lp_servicename(SNUM(conn)), 13); /* Service name */
|
StrnCpy(p+18, lp_servicename(SNUM(conn)), 13); /* Service name */
|
||||||
break;
|
break;
|
||||||
@ -3029,7 +3030,7 @@ int reply_printopen(connection_struct *conn,
|
|||||||
return(ERROR(ERRSRV,ERRnofids));
|
return(ERROR(ERRSRV,ERRnofids));
|
||||||
|
|
||||||
/* Open for exclusive use, write only. */
|
/* Open for exclusive use, write only. */
|
||||||
print_open_file(fsp,conn,"dos.prn");
|
print_fsp_open(fsp,conn,"dos.prn");
|
||||||
|
|
||||||
if (!fsp->open) {
|
if (!fsp->open) {
|
||||||
file_free(fsp);
|
file_free(fsp);
|
||||||
@ -3104,7 +3105,7 @@ int reply_printqueue(connection_struct *conn,
|
|||||||
{
|
{
|
||||||
print_queue_struct *queue = NULL;
|
print_queue_struct *queue = NULL;
|
||||||
char *p = smb_buf(outbuf) + 3;
|
char *p = smb_buf(outbuf) + 3;
|
||||||
int count = get_printqueue(SNUM(conn), conn,&queue,NULL);
|
int count = print_queue_status(SNUM(conn), &queue,NULL);
|
||||||
int num_to_get = ABS(max_count);
|
int num_to_get = ABS(max_count);
|
||||||
int first = (max_count>0?start_index:start_index+max_count+1);
|
int first = (max_count>0?start_index:start_index+max_count+1);
|
||||||
int i;
|
int i;
|
||||||
@ -3118,8 +3119,7 @@ int reply_printqueue(connection_struct *conn,
|
|||||||
for (i=first;i<first+num_to_get;i++) {
|
for (i=first;i<first+num_to_get;i++) {
|
||||||
put_dos_date2(p,0,queue[i].time);
|
put_dos_date2(p,0,queue[i].time);
|
||||||
CVAL(p,4) = (queue[i].status==LPQ_PRINTING?2:3);
|
CVAL(p,4) = (queue[i].status==LPQ_PRINTING?2:3);
|
||||||
SSVAL(p,5,printjob_encode(SNUM(conn),
|
SSVAL(p,5, queue[i].job);
|
||||||
queue[i].job));
|
|
||||||
SIVAL(p,7,queue[i].size);
|
SIVAL(p,7,queue[i].size);
|
||||||
CVAL(p,11) = 0;
|
CVAL(p,11) = 0;
|
||||||
StrnCpy(p+12,queue[i].user,16);
|
StrnCpy(p+12,queue[i].user,16);
|
||||||
|
@ -758,6 +758,10 @@ static void usage(char *pname)
|
|||||||
if (!locking_init(0))
|
if (!locking_init(0))
|
||||||
exit(1);
|
exit(1);
|
||||||
|
|
||||||
|
if (!print_backend_init()) {
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
if(!initialize_password_db())
|
if(!initialize_password_db())
|
||||||
exit(1);
|
exit(1);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user