diff options
author | Andrew Tridgell <tridge@samba.org> | 1996-08-13 08:57:55 +0000 |
---|---|---|
committer | Andrew Tridgell <tridge@samba.org> | 1996-08-13 08:57:55 +0000 |
commit | 396311075cc808278e6dd8469e3ac7eb7e7498c7 (patch) | |
tree | 565884c6c1e72474545c23dc4b6265cb34481b62 | |
parent | 571fe7fbefe4cd62ddb88a4e7bfd69199dcb89e0 (diff) | |
download | samba-396311075cc808278e6dd8469e3ac7eb7e7498c7.tar.gz samba-396311075cc808278e6dd8469e3ac7eb7e7498c7.tar.bz2 samba-396311075cc808278e6dd8469e3ac7eb7e7498c7.zip |
- sequent-ptx support from bressler@iftccu.ca.boeing.com (Rick
Bressler)
- machten support from Trevor Strohman (trev@figment.tenon.com)
- added qinfo command to client as part of drag-and-drop printer
support for win95 from David Chappell <chappell@mouse.cc.trincoll.edu>
He also added the "printer driver" option
- use sigblock() on more systems and use sigsetmask(0) instead of
sigunblock() as its more portable. This beats a problem with zombies
on heavilily loaded systems.
- added internals.doc written by David Chappell into the source tree
- get rid of PRINT_COMMAND options from local.h as they are no longer
relevent
- new kanji code from Fujita
- don't set the recursion_available flag on queries in nmbd
- fix a potential bug with pointer subtraction in printing.c
- got rid of error_count code as the real fix (the EOF problem) is now
in
(This used to be commit aa6f8b04d125b5bc00f267abf72b800228aabf7d)
-rw-r--r-- | source3/client/client.c | 138 | ||||
-rw-r--r-- | source3/include/includes.h | 9 | ||||
-rw-r--r-- | source3/include/local.h | 11 | ||||
-rw-r--r-- | source3/include/proto.h | 5 | ||||
-rw-r--r-- | source3/internals.doc | 212 | ||||
-rw-r--r-- | source3/lib/system.c | 7 | ||||
-rw-r--r-- | source3/lib/util.c | 2 | ||||
-rw-r--r-- | source3/libsmb/namequery.c | 4 | ||||
-rw-r--r-- | source3/libsmb/nmblib.c | 3 | ||||
-rw-r--r-- | source3/namepacket.c | 2 | ||||
-rw-r--r-- | source3/param/loadparm.c | 4 | ||||
-rw-r--r-- | source3/printing/printing.c | 5 | ||||
-rw-r--r-- | source3/smbd/ipc.c | 16 | ||||
-rw-r--r-- | source3/smbd/mangle.c | 54 | ||||
-rw-r--r-- | source3/smbd/server.c | 23 |
15 files changed, 442 insertions, 53 deletions
diff --git a/source3/client/client.c b/source3/client/client.c index 7c4795a8c3..a6bb50cb3d 100644 --- a/source3/client/client.c +++ b/source3/client/client.c @@ -827,6 +827,34 @@ static BOOL do_this_one(file_info *finfo) return(True); } + +/***************************************************************************** + Convert a character pointer in a 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 < 0 || offset >= rdrcnt ) + { + DEBUG(1,("bad char ptr: datap=%u, converter=%u, rdata=%u, rdrcnt=%d>", datap, converter, (unsigned)rdata, rdrcnt)); + return "<ERROR>"; + } + else + { + return &rdata[offset]; + } + } +} + /**************************************************************************** interpret a short filename structure The length of the structure is returned @@ -2177,7 +2205,7 @@ static void do_cancel(int job) bzero(param,sizeof(param)); p = param; - SSVAL(p,0,81); /* api number */ + SSVAL(p,0,81); /* DosPrintJobDel() */ p += 2; strcpy(p,"W"); p = skip_string(p,1); @@ -2424,7 +2452,7 @@ static void cmd_print(char *inbuf,char *outbuf ) } /**************************************************************************** -print a file +show a print queue ****************************************************************************/ static void cmd_queue(char *inbuf,char *outbuf ) { @@ -2486,6 +2514,109 @@ static void cmd_queue(char *inbuf,char *outbuf ) /**************************************************************************** +show information about a print queue +****************************************************************************/ +static void cmd_qinfo(char *inbuf,char *outbuf ) +{ + char *rparam = NULL; + char *rdata = NULL; + char *p; + int rdrcnt, rprcnt; + pstring param; + int result_code; + + bzero(param,sizeof(param)); + + p = param; + SSVAL(p,0,70); /* API function number 70 (DosPrintQGetInfo) */ + p += 2; + strcpy(p,"zWrLh"); /* parameter description? */ + p = skip_string(p,1); + strcpy(p,"zWWWWzzzzWWzzl"); /* returned data format */ + p = skip_string(p,1); + strcpy(p,strrchr(service,'\\')+1); /* name of queue */ + p = skip_string(p,1); + SSVAL(p,0,3); /* API function level 3, just queue info, no job info */ + SSVAL(p,2,1000); /* size of bytes of returned data buffer */ + p += 4; + strcpy(p,""); /* subformat */ + p = skip_string(p,1); + + DEBUG(1,("Calling DosPrintQueueGetInfo()...\n")); + if( call_api(PTR_DIFF(p,param), 0, + 10, 4096, + &rprcnt, &rdrcnt, + param, NULL, + &rparam, &rdata) ) + { + int converter; + result_code = SVAL(rparam,0); + converter = SVAL(rparam,2); /* conversion factor */ + + DEBUG(2,("returned %d bytes of parameters, %d bytes of data, %d records\n", rprcnt, rdrcnt, SVAL(rparam,4) )); + + if (result_code == 0) /* if no error, */ + { + p = rdata; /* received data */ + + printf("Name: \"%s\"\n", fix_char_ptr(SVAL(p,0), converter, rdata, rdrcnt) ); + printf("Priority: %u\n", SVAL(p,4) ); + printf("Start time: %u\n", SVAL(p,6) ); + printf("Until time: %u\n", SVAL(p,8) ); + printf("Seperator file: \"%s\"\n", fix_char_ptr(SVAL(p,12), converter, rdata, rdrcnt) ); + printf("Print processor: \"%s\"\n", fix_char_ptr(SVAL(p,16), converter, rdata, rdrcnt) ); + printf("Parameters: \"%s\"\n", fix_char_ptr(SVAL(p,20), converter, rdata, rdrcnt) ); + printf("Comment: \"%s\"\n", fix_char_ptr(SVAL(p,24), converter, rdata, rdrcnt) ); + printf("Status: %u\n", SVAL(p,28) ); + printf("Jobs: %u\n", SVAL(p,30) ); + printf("Printers: \"%s\"\n", fix_char_ptr(SVAL(p,32), converter, rdata, rdrcnt) ); + printf("Drivername: \"%s\"\n", fix_char_ptr(SVAL(p,36), converter, rdata, rdrcnt) ); + + /* Dump the driver data */ + { + int count, x, y, c; + char *ddptr; + + ddptr = rdata + SVAL(p,40) - converter; + if( SVAL(p,40) == 0 ) {count = 0;} else {count = IVAL(ddptr,0);} + printf("Driverdata: size=%d, version=%u\n", count, IVAL(ddptr,4) ); + + for(x=8; x < count; x+=16) + { + for(y=0; y < 16; y++) + { + if( (x+y) < count ) + printf("%2.2X ", CVAL(ddptr,(x+y)) ); + else + fputs(" ", stdout); + } + for(y=0; y < 16 && (x+y) < count; y++) + { + c = CVAL(ddptr,(x+y)); + if(isprint(c)) + fputc(c, stdout); + else + fputc('.', stdout); + } + fputc('\n', stdout); + } + } + + } + } + else /* call_api() failed */ + { + printf("Failed, error = %d\n", result_code); + } + + /* If any parameters or data were returned, free the storage. */ + if(rparam) free(rparam); + if(rdata) free(rdata); + + return; +} + +/**************************************************************************** delete some files ****************************************************************************/ static void do_del(file_info *finfo) @@ -3544,7 +3675,7 @@ static void server_info() bzero(param,sizeof(param)); p = param; - SSVAL(p,0,63); /* api number */ + SSVAL(p,0,63); /* NetServerGetInfo()? */ p += 2; strcpy(p,"WrLh"); p = skip_string(p,1); @@ -3741,6 +3872,7 @@ struct {"print",cmd_print,"<file name> print a file"}, {"printmode",cmd_printmode,"<graphics or text> set the print mode"}, {"queue",cmd_queue,"show the print queue"}, + {"qinfo",cmd_qinfo,"show print queue information"}, {"cancel",cmd_cancel,"<jobid> cancel a print queue entry"}, {"stat",cmd_stat,"<file> get info on a file (experimental!)"}, {"quit",send_logout,"logoff the server"}, diff --git a/source3/include/includes.h b/source3/include/includes.h index 56a63d46ae..bcf79ac79a 100644 --- a/source3/include/includes.h +++ b/source3/include/includes.h @@ -223,6 +223,7 @@ Here come some platform specific sections #define USE_SETSID #define HAVE_BZERO #define HAVE_MEMMOVE +#define USE_SIGBLOCK #if _LINUX_C_LIB_VERSION_MAJOR >= 5 #define USE_SETFS #endif @@ -255,6 +256,7 @@ typedef unsigned short mode_t; #endif #define REPLACE_GETPASS #define BSD_TERMIO +#define USE_SIGBLOCK #endif @@ -288,6 +290,7 @@ extern int innetgr (const char *, const char *, const char *, const char *); #define USE_GETCWD #define USE_SETSID #define REPLACE_GETPASS +#define USE_SIGBLOCK #endif @@ -479,6 +482,7 @@ char *mktemp(char *); /* No standard include */ #include <netinet/tcp.h> #define SYSV #define USE_WAITPID +#define USE_SIGBLOCK #define SIGNAL_CAST (void (*)()) #define DEFAULT_PRINTING PRINT_AIX /* we undef this because sys/param.h is broken in aix. uggh. */ @@ -529,7 +533,12 @@ char *mktemp(char *); /* No standard include */ #define NO_EID #define STATFS4 #define USE_DIRECT +#ifdef PTX4 +#undef USE_DIRECT #endif +#endif + + #ifdef SEQUENT_PTX4 #include <string.h> diff --git a/source3/include/local.h b/source3/include/local.h index 2cfacd66b3..5a577909e1 100644 --- a/source3/include/local.h +++ b/source3/include/local.h @@ -53,17 +53,6 @@ /* this is where browse lists are kept in the lock dir */ #define SERVER_LIST "browse.dat" -/* the print command on the server, %s is replaced with the filename */ -/* note that the -r removes the file after printing - you'll run out */ -/* of disk pretty quickly if you don't. This command is only used as */ -/* the default - it can be overridden in the configuration file. */ -#define PRINT_COMMAND "lpr -r %s" - -/* the lpq command on the server. the printername is passed as an argument */ -#ifndef LPQ_COMMAND -#define LPQ_COMMAND "lpq -P" -#endif - /* shall guest entries in printer queues get changed to user entries, so they can be deleted using the windows print manager? */ #define LPQ_GUEST_TO_USER diff --git a/source3/include/proto.h b/source3/include/proto.h index 10f2bc3325..4d1c4bf6f9 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -194,6 +194,7 @@ char *lp_lprmcommand(int ); char *lp_lppausecommand(int ); char *lp_lpresumecommand(int ); char *lp_printername(int ); +char *lp_printerdriver(int ); char *lp_hostsallow(int ); char *lp_hostsdeny(int ); char *lp_magicscript(int ); @@ -313,9 +314,6 @@ struct browse_cache_record *add_browser_entry(char *name, int type, char *wg, time_t ttl, struct in_addr ip, BOOL local); void do_browser_lists(void); -/*The following definitions come from namedb.c */ - - /*The following definitions come from namedbname.c */ void set_samba_nb_type(void); @@ -720,6 +718,7 @@ int sys_rmdir(char *dname); int sys_chdir(char *dname); int sys_utime(char *fname,struct utimbuf *times); int sys_rename(char *from, char *to); +int sys_chmod(char *fname,int mode); int sys_chown(char *fname,int uid,int gid); int sys_chroot(char *dname); diff --git a/source3/internals.doc b/source3/internals.doc new file mode 100644 index 0000000000..971f256738 --- /dev/null +++ b/source3/internals.doc @@ -0,0 +1,212 @@ +internals.txt, 8 May 1996 +Written by David Chappell <David.Chappell@mail.trincoll.edu>. + +This document describes some of the internal functions which must be +understood by anyone wishing to add features to Samba. + + + + + +============================================================================= +This section describes the macros defined in byteorder.h. These macros +are used extensively in the Samba code. + +----------------------------------------------------------------------------- +CVAL(buf,pos) + +returns the byte at offset pos within buffer buf as an unsigned character. + +----------------------------------------------------------------------------- +PVAL(buf,pos) + +returns the value of CVAL(buf,pos) cast to type unsigned integer. + +----------------------------------------------------------------------------- +SCVAL(buf,pos,val) + +sets the byte at offset pos within buffer buf to value val. + +----------------------------------------------------------------------------- +SVAL(buf,pos) + +returns the value of the unsigned short (16 bit) little-endian integer at +offset pos within buffer buf. An integer of this type is sometimes +refered to as "USHORT". + +----------------------------------------------------------------------------- +IVAL(buf,pos) + +returns the value of the unsigned 32 bit little-endian integer at offset +pos within buffer buf. + +----------------------------------------------------------------------------- +SVALS(buf,pos) + +returns the value of the signed short (16 bit) little-endian integer at +offset pos within buffer buf. + +----------------------------------------------------------------------------- +IVALS(buf,pos) + +returns the value of the signed 32 bit little-endian integer at offset pos +within buffer buf. + +----------------------------------------------------------------------------- +SSVAL(buf,pos,val) + +sets the unsigned short (16 bit) little-endian integer at offset pos within +buffer buf to value val. + +----------------------------------------------------------------------------- +SIVAL(buf,pos,val) + +sets the unsigned 32 bit little-endian integer at offset pos within buffer +buf to the value val. + +----------------------------------------------------------------------------- +SSVALS(buf,pos,val) + +sets the short (16 bit) signed little-endian integer at offset pos within +buffer buf to the value val. + +----------------------------------------------------------------------------- +SIVALS(buf,pos,val) + +sets the signed 32 bit little-endian integer at offset pos withing buffer +buf to the value val. + +----------------------------------------------------------------------------- +RSVAL(buf,pos) + +returns the value of the unsigned short (16 bit) big-endian integer at +offset pos within buffer buf. + +----------------------------------------------------------------------------- +RIVAL(buf,pos) + +returns the value of the unsigned 32 bit big-endian integer at offset +pos within buffer buf. + +----------------------------------------------------------------------------- +RSSVAL(buf,pos,val) + +sets the value of the unsigned short (16 bit) big-endian integer at +offset pos within buffer buf to value val. +refered to as "USHORT". + +----------------------------------------------------------------------------- +RSIVAL(buf,pos,val) + +sets the value of the unsigned 32 bit big-endian integer at offset +pos within buffer buf to value val. + + + + + +============================================================================= +This section describes the functions need to make a LAN Manager RPC call. +This information had been obtained by examining the Samba code and the LAN +Manager 2.0 API documentation. It should not be considered entirely +reliable. + +----------------------------------------------------------------------------- +call_api(int prcnt, int drcnt, int mprcnt, int mdrcnt, + char *param, char *data, char **rparam, char **rdata); + +This function is defined in client.c. It uses an SMB transaction to call a +remote api. + +The parameters are as follows: + +prcnt: the number of bytes of parameters begin sent. +drcnt: the number of bytes of data begin sent. +mprcnt: the maximum number of bytes of parameters which should be returned +mdrcnt: the maximum number of bytes of data which should be returned +param: a pointer to the parameters to be sent. +data: a pointer to the data to be sent. +rparam: a pointer to a pointer which will be set to point to the returned + paramters. The caller of call_api() must deallocate this memory. +rdata: a pointer to a pointer which will be set to point to the returned + data. The caller of call_api() must deallocate this memory. + +----------------------------------------------------------------------------- +These are the parameters which you ought to send, in the order of their +appearance in the parameter block: + +* An unsigned 16 bit integer API number. You should set this value with +SSVAL(). I do not know where these numbers are described. + +* An ASCIIZ string describing the parameters to the API function as defined +in the LAN Manager documentation. The first parameter, which is the server +name, is ommited. This string is based uppon the API function as described +in the manual, not the data which is actually passed. + +* An ASCIIZ string describing the data structure which ought to be returned. + +* Any parameters which appear in the function call, as defined in the LAN +Manager API documentation, after the "Server" and up to and including the +"uLevel" parameters. + +* An unsigned 16 bit integer which gives the size in bytes of the buffer we +will use to receive the returned array of data structures. Presumably this +should be the same as mdrcnt. This value should be set with SSVAL(). + +* An ASCIIZ string describing substructures which should be returned. If no +substructures apply, this string is of zero length. + +----------------------------------------------------------------------------- +The code in client.c always calls call_api() with no data. It is unclear +when a non-zero length data buffer would be sent. + +----------------------------------------------------------------------------- +The returned parameters (pointed to by rparam), in their order of appearance +are: + +* An unsigned 16 bit integer which contains the API function's return code. +This value should be read with SVAL(). + +* An adjustment which tells the amount by which pointers in the returned +data should be adjusted. This value should be read with SVAL(). Basically, +the address of the start of the returned data buffer should have the returned +pointer value added to it and then have this value subtracted from it in +order to obtain the currect offset into the returned data buffer. + +* A count of the number of elements in the array of structures returned. +It is also possible that this may sometimes be the number of bytes returned. + +----------------------------------------------------------------------------- +When call_api() returns, rparam points to the returned parameters. The +first if these is the result code. It will be zero if the API call +suceeded. This value by be read with "SVAL(rparam,0)". + +The second parameter may be read as "SVAL(rparam,2)". It is a 16 bit offset +which indicates what the base address of the returned data buffer was when +it was built on the server. It should be used to correct pointer before +use. + +The returned data buffer contains the array of returned data structures. +Note that all pointers must be adjusted before use. The function +fix_char_ptr() in client.c can be used for this purpose. + +The third parameter (which may be read as "SVAL(rparam,4)") has something to +do with indicating the amount of data returned or possibly the amount of +data which can be returned if enough buffer space is allowed. + +----------------------------------------------------------------------------- +Certain data structures are described by means of ASCIIz strings containing +code characters. These are the code characters: + +W a type byte little-endian unsigned integer +N a count of substructures which follow +D a four byte little-endian unsigned integer +B a byte (with optional count expressed as trailing ASCII digits) +z a four byte offset to a NULL terminated string +l a four byte offset to non-string user data +b an offset to data (with count expressed as trailing ASCII digits) +r pointer to returned data buffer??? +L length in bytes of returned data buffer??? +h number of bytes of information available??? + +---------------------------------------------------------------------------- diff --git a/source3/lib/system.c b/source3/lib/system.c index 7dc585223a..1410b776ab 100644 --- a/source3/lib/system.c +++ b/source3/lib/system.c @@ -200,6 +200,13 @@ int sys_rename(char *from, char *to) #endif /* KANJI */ } +/******************************************************************* +for chmod +********************************************************************/ +int sys_chmod(char *fname,int mode) +{ + return(chmod(dos_to_unix(fname,False),mode)); +} /******************************************************************* chown isn't used much but OS/2 doesn't have it diff --git a/source3/lib/util.c b/source3/lib/util.c index 6a4861981d..657e9cb1a0 100644 --- a/source3/lib/util.c +++ b/source3/lib/util.c @@ -3127,7 +3127,7 @@ void BlockSignals(BOOL block) if (block) sigblock(block_mask); else - sigunblock(block_mask); + sigsetmask(0); #endif } diff --git a/source3/libsmb/namequery.c b/source3/libsmb/namequery.c index 21d3bd1e50..f1847e38ba 100644 --- a/source3/libsmb/namequery.c +++ b/source3/libsmb/namequery.c @@ -214,8 +214,8 @@ BOOL name_query(int fd,char *name,int name_type, nmb->header.opcode = 0; nmb->header.response = False; nmb->header.nm_flags.bcast = bcast; - nmb->header.nm_flags.recursion_available = 0; - nmb->header.nm_flags.recursion_desired = 1; + nmb->header.nm_flags.recursion_available = False; + nmb->header.nm_flags.recursion_desired = True; nmb->header.nm_flags.trunc = False; nmb->header.nm_flags.authoritative = False; nmb->header.rcode = 0; diff --git a/source3/libsmb/nmblib.c b/source3/libsmb/nmblib.c index 3434f31a33..4113b34cab 100644 --- a/source3/libsmb/nmblib.c +++ b/source3/libsmb/nmblib.c @@ -609,7 +609,8 @@ static int build_nmb(char *buf,struct packet_struct *p) if (nmb->header.nm_flags.authoritative) ubuf[offset+2] |= 0x4; if (nmb->header.nm_flags.trunc) ubuf[offset+2] |= 0x2; if (nmb->header.nm_flags.recursion_desired) ubuf[offset+2] |= 0x1; - if (nmb->header.nm_flags.recursion_available) ubuf[offset+3] |= 0x80; + if (nmb->header.nm_flags.recursion_available && + nmb->header.response) ubuf[offset+3] |= 0x80; if (nmb->header.nm_flags.bcast) ubuf[offset+3] |= 0x10; ubuf[offset+3] |= (nmb->header.rcode & 0xF); diff --git a/source3/namepacket.c b/source3/namepacket.c index acedbc0151..a752ef5dfa 100644 --- a/source3/namepacket.c +++ b/source3/namepacket.c @@ -125,7 +125,7 @@ void initiate_netbios_packet(uint16 *id, nmb->header.response = False; nmb->header.nm_flags.bcast = bcast; - nmb->header.nm_flags.recursion_available = CanRecurse; + nmb->header.nm_flags.recursion_available = False; nmb->header.nm_flags.recursion_desired = recurse; nmb->header.nm_flags.trunc = False; nmb->header.nm_flags.authoritative = False; diff --git a/source3/param/loadparm.c b/source3/param/loadparm.c index f4aaa16e6a..7877f2eb99 100644 --- a/source3/param/loadparm.c +++ b/source3/param/loadparm.c @@ -192,6 +192,7 @@ typedef struct char *szLppausecommand; char *szLpresumecommand; char *szPrintername; + char *szPrinterDriver; char *szDontdescend; char *szHostsallow; char *szHostsdeny; @@ -264,6 +265,7 @@ static service sDefault = NULL, /* szLppausecommand */ NULL, /* szLpresumecommand */ NULL, /* szPrintername */ + NULL, /* szPrinterDriver */ NULL, /* szDontdescend */ NULL, /* szHostsallow */ NULL, /* szHostsdeny */ @@ -491,6 +493,7 @@ struct parm_struct {"lpresume command", P_STRING, P_LOCAL, &sDefault.szLpresumecommand,NULL}, {"printer", P_STRING, P_LOCAL, &sDefault.szPrintername, NULL}, {"printer name", P_STRING, P_LOCAL, &sDefault.szPrintername, NULL}, + {"printer driver", P_STRING, P_LOCAL, &sDefault.szPrinterDriver, NULL}, {"hosts allow", P_STRING, P_LOCAL, &sDefault.szHostsallow, NULL}, {"allow hosts", P_STRING, P_LOCAL, &sDefault.szHostsallow, NULL}, {"hosts deny", P_STRING, P_LOCAL, &sDefault.szHostsdeny, NULL}, @@ -759,6 +762,7 @@ FN_LOCAL_STRING(lp_lprmcommand,szLprmcommand) FN_LOCAL_STRING(lp_lppausecommand,szLppausecommand) FN_LOCAL_STRING(lp_lpresumecommand,szLpresumecommand) FN_LOCAL_STRING(lp_printername,szPrintername) +FN_LOCAL_STRING(lp_printerdriver,szPrinterDriver) FN_LOCAL_STRING(lp_hostsallow,szHostsallow) FN_LOCAL_STRING(lp_hostsdeny,szHostsdeny) FN_LOCAL_STRING(lp_magicscript,szMagicScript) diff --git a/source3/printing/printing.c b/source3/printing/printing.c index 2eef0d303b..7ffded8e91 100644 --- a/source3/printing/printing.c +++ b/source3/printing/printing.c @@ -73,7 +73,7 @@ static char *build_print_command(int cnum, char *command, char *syscmd, char *fi } if (strstr(syscmd,"%s")) { - int iOffset = strstr(syscmd, "%s") - syscmd; + int iOffset = PTR_DIFF(strstr(syscmd, "%s"),syscmd); /* construct the full path for the filename, shouldn't be necessary unless the subshell causes a "cd" to be executed. @@ -713,6 +713,9 @@ static BOOL parse_lpq_entry(int snum,char *line, } #endif + /* We don't want the newline in the status message. */ + line[strcspn(line,"\n")] = (char)NULL; + if (status && !ret) { /* a few simple checks to see if the line might be a diff --git a/source3/smbd/ipc.c b/source3/smbd/ipc.c index f4f1807922..0a54936cd0 100644 --- a/source3/smbd/ipc.c +++ b/source3/smbd/ipc.c @@ -190,12 +190,6 @@ static void send_trans_reply(char *outbuf,char *data,char *param,uint16 *setup, } } - - -/**************************************************************************** - get a print queue - ****************************************************************************/ - struct pack_desc { char* format; /* formatstring for structure */ char* subformat; /* subformat for structure */ @@ -419,6 +413,11 @@ static void PACKS(struct pack_desc* desc,char *t,char *v) PACK(desc,t,v); } + +/**************************************************************************** + get a print queue + ****************************************************************************/ + static void PackDriverData(struct pack_desc* desc) { char drivdata[4+4+32]; @@ -546,7 +545,7 @@ static void fill_printq_info(int cnum, int snum, int uLevel, PACKI(desc,"W",0); /* uUntiltime */ PACKI(desc,"W",5); /* pad1 */ PACKS(desc,"z",""); /* pszSepFile */ - PACKS(desc,"z","lpd"); /* pszPrProc */ + PACKS(desc,"z","WinPrint"); /* pszPrProc */ PACKS(desc,"z",""); /* pszParms */ if (!status || !status->message[0]) { PACKS(desc,"z",Expand(cnum,snum,lp_comment(snum))); /* pszComment */ @@ -557,7 +556,7 @@ static void fill_printq_info(int cnum, int snum, int uLevel, } PACKI(desc,(uLevel == 3 ? "W" : "N"),count); /* cJobs */ PACKS(desc,"z",SERVICE(snum)); /* pszPrinters */ - PACKS(desc,"z","NULL"); /* pszDriverName */ + PACKS(desc,"z",lp_printerdriver(snum)); /* pszDriverName */ PackDriverData(desc); /* pDriverData */ } if (uLevel == 2 || uLevel == 4) { @@ -594,6 +593,7 @@ static BOOL api_DosPrintQGetInfo(int cnum,int uid, char *param,char *data, cbBuf = SVAL(p,2); str3 = p + 4; + /* remove any trailing username */ if ((p = strchr(QueueName,'%'))) *p = 0; DEBUG(3,("PrintQueue uLevel=%d name=%s\n",uLevel,QueueName)); diff --git a/source3/smbd/mangle.c b/source3/smbd/mangle.c index cf1ece558c..177a34c975 100644 --- a/source3/smbd/mangle.c +++ b/source3/smbd/mangle.c @@ -509,9 +509,36 @@ void mangle_name_83(char *s) *p++ = 0; while (*p && extlen < 3) { +#ifdef KANJI + if (is_shift_jis (*p)) + { + if (extlen < 2) + { + extension[extlen++] = p[0]; + extension[extlen++] = p[1]; + } + else + { + extension[extlen++] = base36 (((unsigned char) *p) % 36); + } + p += 2; + } + else if (is_kana (*p)) + { + extension[extlen++] = p[0]; + p++; + } + else + { + if (isdoschar (*p) && *p != '.') + extension[extlen++] = p[0]; + p++; + } +#else if (isdoschar(*p) && *p != '.') extension[extlen++] = *p; p++; +#endif /* KANJI */ } extension[extlen] = 0; } @@ -521,9 +548,36 @@ void mangle_name_83(char *s) while (*p && baselen < 5) { +#ifdef KANJI + if (is_shift_jis (*p)) + { + if (baselen < 4) + { + base[baselen++] = p[0]; + base[baselen++] = p[1]; + } + else + { + base[baselen++] = base36 (((unsigned char) *p) % 36); + } + p += 2; + } + else if (is_kana (*p)) + { + base[baselen++] = p[0]; + p++; + } + else + { + if (isdoschar (*p) && *p != '.') + base[baselen++] = p[0]; + p++; + } +#else if (isdoschar(*p) && *p != '.') base[baselen++] = *p; p++; +#endif /* KANJI */ } base[baselen] = 0; diff --git a/source3/smbd/server.c b/source3/smbd/server.c index d15ca9336e..334edf77d0 100644 --- a/source3/smbd/server.c +++ b/source3/smbd/server.c @@ -230,7 +230,7 @@ int dos_chmod(int cnum,char *fname,int dosmode,struct stat *st) unixmode |= tmp; } - return(chmod(fname,unixmode)); + return(sys_chmod(fname,unixmode)); } @@ -3443,27 +3443,6 @@ static void process(void) t = time(NULL); - { - /* the following bit of code was added to combat smbd - looping chewing lots of CPU time. It should never - actually be needed, but it seems that some systems - don't set error correctly, which is used to distinguish - a select() timeout from a read error - - we exit if receive_smb() returns false 3 times in one second. - */ - static int error_count=0; - static time_t error_time=0; - if (error_count++==0) { - error_time = t; - } else if (error_time != t) { - error_count = 0; - } else if (error_count > 2) { - exit_server("looping in process()\n"); - } - } - - /* become root again if waiting */ unbecome_user(); |