home *** CD-ROM | disk | FTP | other *** search
- /*
- Unix SMB/Netbios implementation.
- Version 1.8.
- Copyright (C) Andrew Tridgell 1992,1993,1994
-
- 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
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- 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.
- */
- /*
- This file handles most of the reply_ calls that the server
- makes to handle specific protocols
- */
-
-
- #include "includes.h"
- #include "loadparm.h"
- #include "trans2.h"
-
- /* look in server.c for some explanation of these variables */
- extern int Protocol;
- extern int DEBUGLEVEL;
- extern int chain_size;
- extern int maxxmit;
- extern int num_files_open;
- extern int chain_fnum;
- extern char magic_char;
- extern BOOL long_filenames;
- extern BOOL casesignames;
- extern connection_struct Connections[];
- extern files_struct Files[];
-
- /* this macro should always be used to extract an fnum (smb_fid) from
- a packet to ensure chaining works correctly */
- #define GETFNUM(buf,where) (chain_fnum!=-1?chain_fnum:SVAL(buf,where))
-
- /****************************************************************************
- reply to an special message
- ****************************************************************************/
- int reply_special(char *inbuf,char *outbuf)
- {
- int outsize = 4;
- int msg_type = CVAL(inbuf,0);
- int msg_flags = CVAL(inbuf,1);
- pstring name1="";
- pstring name2="";
-
- switch (msg_type)
- {
- case 0x81: /* session request */
- CVAL(outbuf,0) = 0x82;
- CVAL(outbuf,3) = 0;
- name_interpret(inbuf + 4,name1);
- name_interpret(inbuf + 4 + name_len(inbuf + 4),name2);
- DEBUG(2,("netbios connect: name1=%s name2=%s\n",name1,name2));
- {
- char *p;
- extern fstring remote_machine;
- strcpy(remote_machine,name2);
- trim_string(remote_machine," "," ");
- p = strchr(remote_machine,' ');
- if (p) *p = 0;
- }
- if (Get_Pwnam(name2))
- add_session_user(name2);
- break;
- case 0x85: /* session keepalive */
- default:
- return(0);
- }
-
- DEBUG(5,("%s init msg_type=0x%x msg_flags=0x%x\n",timestring(),msg_type,msg_flags));
-
- smb_setlen(outbuf,0);
- return(outsize);
- }
-
-
-
- /****************************************************************************
- reply to a tcon
- ****************************************************************************/
- int reply_tcon(char *inbuf,char *outbuf)
- {
- pstring service="";
- pstring user="";
- pstring password="";
- pstring dev="";
- int connection_num;
- int outsize = 0;
- int uid = SVAL(inbuf,smb_uid);
- int vuid;
-
- vuid = valid_uid(uid);
-
- parse_connect(inbuf,service,user,password,dev);
-
- connection_num = make_connection(service,user,password,dev,vuid);
-
- if (connection_num < 0)
- switch (connection_num)
- {
- case -4:
- return(ERROR(ERRSRV,ERRaccess));
- case -3:
- return(ERROR(ERRDOS,ERRnoipc));
- case -2:
- return(ERROR(ERRSRV,ERRinvnetname));
- default:
- return(ERROR(ERRSRV,ERRbadpw));
- }
-
- outsize = set_message(outbuf,2,0,True);
- SSVAL(outbuf,smb_vwv0,MIN(lp_maxxmit(),BUFFER_SIZE)-4);
- SSVAL(outbuf,smb_vwv1,connection_num);
- SSVAL(outbuf,smb_tid,connection_num);
-
- DEBUG(3,("%s tcon service=%s user=%s cnum=%d\n",timestring(),service,user,connection_num));
-
- return(outsize);
- }
-
-
- /****************************************************************************
- reply to a tcon and X
- ****************************************************************************/
- int reply_tcon_and_X(char *inbuf,char *outbuf,int length,int bufsize)
- {
- pstring service="";
- pstring user="";
- pstring password="";
- pstring devicename="";
- int connection_num;
- int outsize = 0;
- int uid = SVAL(inbuf,smb_uid);
- int vuid;
- int smb_com2 = SVAL(inbuf,smb_vwv0);
- int smb_off2 = SVAL(inbuf,smb_vwv1);
-
- /* we might have to close an old one */
- if ((SVAL(inbuf,smb_vwv2) & 0x1) != 0)
- close_cnum(SVAL(inbuf,smb_tid));
-
- vuid = valid_uid(uid);
-
- {
- int passlen = SVAL(inbuf,smb_vwv3);
- char *path;
- char *p;
- memcpy(password,smb_buf(inbuf),passlen);
- password[passlen]=0;
- path = smb_buf(inbuf) + passlen;
- DEBUG(4,("parsing net-path %s, passlen=%d\n",path,passlen));
- strcpy(service,path+2);
- p = strchr(service,'\\');
- if (!p)
- return(ERROR(ERRSRV,ERRinvnetname));
- *p = 0;
- strcpy(service,p+1);
- p = strchr(service,'%');
- if (p)
- {
- *p++ = 0;
- strcpy(user,p);
- }
- strcpy(devicename,path + strlen(path) + 1);
- DEBUG(4,("Got device type %s\n",devicename));
- }
-
- connection_num = make_connection(service,user,password,devicename,vuid);
-
- if (connection_num < 0)
- switch (connection_num)
- {
- case -4:
- return(ERROR(ERRSRV,ERRaccess));
- case -3:
- return(ERROR(ERRDOS,ERRnoipc));
- case -2:
- return(ERROR(ERRSRV,ERRinvnetname));
- default:
- return(ERROR(ERRSRV,ERRbadpw));
- }
-
- outsize = set_message(outbuf,2,strlen(devicename)+1,True);
-
- DEBUG(3,("%s tconX service=%s user=%s cnum=%d\n",timestring(),service,user,connection_num));
-
- /* set the incoming and outgoing tid to the just created one */
- SSVAL(inbuf,smb_tid,connection_num);
- SSVAL(outbuf,smb_tid,connection_num);
-
- CVAL(outbuf,smb_vwv0) = smb_com2;
- SSVAL(outbuf,smb_vwv1,(chain_size + outsize)-4);
-
- strcpy(smb_buf(outbuf),devicename);
-
- if (smb_com2 != 0xFF)
- outsize += chain_reply(smb_com2,inbuf,inbuf+smb_off2+4,
- outbuf,outbuf+outsize,
- length,bufsize);
-
- return(outsize);
- }
-
-
- /****************************************************************************
- reply to an unknown type
- ****************************************************************************/
- int reply_unknown(char *inbuf,char *outbuf)
- {
- int cnum;
- int type;
- cnum = SVAL(inbuf,smb_tid);
- type = CVAL(inbuf,smb_com);
-
- DEBUG(0,("%s unknown command type (%s): cnum=%d type=%d (0x%X)\n",
- timestring(),
- smb_fn_name(type),
- cnum,type,type));
-
- return(ERROR(ERRSRV,ERRnosupport));
- }
-
-
- /****************************************************************************
- reply to an ioctl
- ****************************************************************************/
- int reply_ioctl(char *inbuf,char *outbuf)
- {
- DEBUG(3,("ignoring ioctl\n"));
-
- return(ERROR(ERRSRV,ERRnosupport));
- }
-
-
- /****************************************************************************
- reply to a session setup command
- ****************************************************************************/
- int reply_sesssetup_and_X(char *inbuf,char *outbuf,int length,int bufsize)
- {
- int outsize = 0;
- int sess_uid;
- int smb_com2;
- int smb_off2;
- int smb_bufsize;
- int smb_mpxmax;
- int smb_vc_num;
- uint32 smb_sesskey;
- int smb_apasslen;
- pstring smb_apasswd="";
- pstring smb_aname="";
- BOOL guest=False;
-
- sess_uid = SVAL(inbuf,smb_uid);
- smb_com2 = CVAL(inbuf,smb_vwv0);
- smb_off2 = SVAL(inbuf,smb_vwv1);
- smb_bufsize = SVAL(inbuf,smb_vwv2);
- smb_mpxmax = SVAL(inbuf,smb_vwv3);
- smb_vc_num = SVAL(inbuf,smb_vwv4);
- smb_sesskey = IVAL(inbuf,smb_vwv5);
- smb_apasslen = SVAL(inbuf,smb_vwv7);
-
- StrnCpy(smb_apasswd,smb_buf(inbuf),smb_apasslen);
- StrnCpy(smb_aname,smb_buf(inbuf)+smb_apasslen,sizeof(smb_aname)-1);
-
- DEBUG(3,("sesssetupX:name=[%s]\n",smb_aname));
-
- strlower(smb_aname);
-
- if (Get_Pwnam(smb_aname))
- add_session_user(smb_aname);
-
- if (!check_hosts_equiv(smb_aname))
- {
-
- if (strequal(smb_aname,lp_guestaccount()) && (*smb_apasswd == 0))
- guest = True;
-
- /* now check if it's a valid username/password */
- if (!guest && !password_ok(smb_aname,smb_apasswd, NULL))
- {
- DEBUG(3,("Registered username %s for guest access\n",smb_aname));
- if (*smb_apasswd || !Get_Pwnam(smb_aname))
- strcpy(smb_aname,lp_guestaccount());
- guest = True;
- }
- }
-
- if (!strequal(smb_aname,lp_guestaccount()))
- {
- int homes = lp_servicenumber(HOMES_NAME);
- char *home = get_home_dir(smb_aname);
- if (homes >= 0 && home)
- lp_add_home(smb_aname,homes,home);
- }
-
-
- /* it's ok - setup a reply */
- outsize = set_message(outbuf,3,0,True);
-
- CVAL(outbuf,smb_vwv0) = smb_com2;
- SSVAL(outbuf,smb_vwv1,(chain_size+outsize)-4);
-
- if (guest)
- SSVAL(outbuf,smb_vwv2,1);
-
- /* register the name and uid as being validated, so further connections
- to a uid can get through without a password, on the same VC */
- register_uid(SVAL(inbuf,smb_uid),smb_aname,guest);
-
- if (smb_com2 != 0xFF)
- outsize += chain_reply(smb_com2,inbuf,inbuf+smb_off2+4,
- outbuf,outbuf+outsize,
- length,bufsize);
-
- maxxmit = MIN(lp_maxxmit(),smb_bufsize);
-
- return(outsize);
- }
-
-
- /****************************************************************************
- reply to a chkpth
- ****************************************************************************/
- int reply_chkpth(char *inbuf,char *outbuf)
- {
- int outsize = 0;
- int cnum,mode;
- pstring name="";
- BOOL ok = False;
-
- cnum = SVAL(inbuf,smb_tid);
-
- strcpy(name,smb_buf(inbuf) + 1);
- unix_convert(name,cnum);
-
- mode = SVAL(inbuf,smb_vwv0);
-
- if (check_name(name,cnum))
- ok = directory_exist(name);
-
- if (!ok)
- return(ERROR(ERRDOS,ERRbadpath));
-
- outsize = set_message(outbuf,0,0,True);
-
- DEBUG(3,("%s chkpth %s cnum=%d mode=%d\n",timestring(),name,cnum,mode));
-
- return(outsize);
- }
-
-
- /****************************************************************************
- reply to a getatr
- ****************************************************************************/
- int reply_getatr(char *inbuf,char *outbuf)
- {
- pstring fname="";
- int cnum;
- int outsize = 0;
- struct stat sbuf;
- BOOL ok = False;
- int mode=0;
- uint32 size=0;
- time_t mtime=0;
-
- cnum = SVAL(inbuf,smb_tid);
-
- strcpy(fname,smb_buf(inbuf) + 1);
- unix_convert(fname,cnum);
-
- /* dos smetimes asks for a stat of "" - it returns a "hidden directory"
- under WfWg - weird! */
- if (! (*fname))
- {
- mode = 0x12;
- size = 0;
- mtime = 0;
- ok = True;
- }
- else
- if (check_name(fname,cnum))
- {
- if (stat(fname,&sbuf) == 0)
- {
- mode = dos_mode(cnum,fname,&sbuf);
- size = sbuf.st_size;
- mtime = sbuf.st_mtime;
- if (mode & aDIR)
- size = 0;
- ok = True;
- }
- else
- DEBUG(3,("stat of %s failed (%s)\n",fname,strerror(errno)));
- }
-
- if (!ok)
- return(UNIXERROR(ERRDOS,ERRbadfile));
-
- outsize = set_message(outbuf,10,0,True);
-
- SSVAL(outbuf,smb_vwv0,mode);
- SIVAL(outbuf,smb_vwv1,mtime + GMT_TO_LOCAL * TimeDiff());
- SIVAL(outbuf,smb_vwv3,size);
-
- DEBUG(3,("%s getatr name=%s mode=%d size=%d\n",timestring(),fname,mode,size));
-
- return(outsize);
- }
-
-
- /****************************************************************************
- reply to a setatr
- ****************************************************************************/
- int reply_setatr(char *inbuf,char *outbuf)
- {
- pstring fname="";
- int cnum;
- int outsize = 0;
- BOOL ok=False;
- int mode;
- time_t mtime;
-
- cnum = SVAL(inbuf,smb_tid);
-
- strcpy(fname,smb_buf(inbuf) + 1);
- unix_convert(fname,cnum);
-
- mode = SVAL(inbuf,smb_vwv0);
- mtime = IVAL(inbuf,smb_vwv1);
-
- if (directory_exist(fname))
- mode |= aDIR;
- if (check_name(fname,cnum))
- ok = (chmod(fname,unix_mode(cnum,mode)) == 0);
- if (ok && mtime != 0)
- ok = set_filetime(fname,mtime + LOCAL_TO_GMT * TimeDiff());
-
- if (!ok)
- return(UNIXERROR(ERRDOS,ERRnoaccess));
-
- outsize = set_message(outbuf,0,0,True);
-
- DEBUG(3,("%s setatr name=%s mode=%d\n",timestring(),fname,mode));
-
- return(outsize);
- }
-
-
- /****************************************************************************
- reply to a dskattr
- ****************************************************************************/
- int reply_dskattr(char *inbuf,char *outbuf)
- {
- int cnum;
- int outsize = 0;
- int dfree,dsize,bsize;
-
- cnum = SVAL(inbuf,smb_tid);
-
- disk_free(".",&bsize,&dfree,&dsize);
-
- outsize = set_message(outbuf,5,0,True);
-
- SSVAL(outbuf,smb_vwv0,dsize);
- SSVAL(outbuf,smb_vwv1,1);
- SSVAL(outbuf,smb_vwv2,bsize);
- SSVAL(outbuf,smb_vwv3,dfree);
-
- DEBUG(3,("%s dskattr cnum=%d dfree=%d\n",timestring(),cnum,dfree));
-
- return(outsize);
- }
-
-
- /****************************************************************************
- reply to a search
- Can be called from SMBsearch, SMBffirst or SMBfunique.
- ****************************************************************************/
- int reply_search(char *inbuf,char *outbuf)
- {
- pstring mask="";
- pstring directory="";
- pstring fname="";
- int size,mode;
- time_t date;
- int dirtype;
- int cnum;
- int outsize = 0;
- int numentries = 0;
- BOOL finished = False;
- int maxentries;
- int i;
- char *p;
- BOOL ok = False;
- int status_len;
- char *path;
- char status[21];
- int dptr_num=-1;
- BOOL check_descend = False;
- BOOL expect_close = False;
-
- /* If we were called as SMBffirst then we must expect close. */
- if(CVAL(inbuf,smb_com) == SMBffirst)
- expect_close = True;
-
- cnum = SVAL(inbuf,smb_tid);
-
- outsize = set_message(outbuf,1,3,True);
- maxentries = SVAL(inbuf,smb_vwv0);
- dirtype = SVAL(inbuf,smb_vwv1);
- path = smb_buf(inbuf) + 1;
- status_len = SVAL(smb_buf(inbuf),3 + strlen(path));
-
-
- /* dirtype &= ~aDIR; */
-
- DEBUG(5,("path=%s status_len=%d\n",path,status_len));
-
-
- if (status_len == 0)
- {
- pstring dir2;
-
- strcpy(directory,smb_buf(inbuf)+1);
- strcpy(dir2,smb_buf(inbuf)+1);
- unix_convert(directory,cnum);
- unix_format(dir2);
-
- if (!check_name(directory,cnum))
- return(ERROR(ERRDOS,ERRbadpath));
-
- p = strrchr(dir2,'/');
- if (p == NULL)
- {strcpy(mask,dir2);*dir2 = 0;}
- else
- {*p = 0;strcpy(mask,p+1);}
-
- p = strrchr(directory,'/');
- if (!p)
- *directory = 0;
- else
- *p = 0;
-
- if (strlen(directory) == 0)
- strcpy(directory,"./");
- memset(status,0,21);
- CVAL(status,0) = dirtype;
- }
- else
- {
- memcpy(status,smb_buf(inbuf) + 1 + strlen(path) + 4,21);
- memcpy(mask,status+1,11);
- mask[11] = 0;
- Connections[cnum].dirptr = dptr_fetch(status+12,&dptr_num);
- dirtype = CVAL(status,0) & 0x1F;
- if (!Connections[cnum].dirptr)
- return(ERROR(ERRDOS,ERRnofiles));
- StrnCpy(Connections[cnum].dirpath,dptr_path(dptr_num),sizeof(pstring)-1);
- strlower(mask);
- }
-
-
- DEBUG(5,("mask=%s directory=%s\n",mask,directory));
- CVAL(smb_buf(outbuf),0) = 5;
-
- {
- char *p = smb_buf(outbuf) + 3;
-
- ok = True;
-
- if (status_len == 0)
- {
- if (!start_dir(cnum,directory))
- ok = False;
- else
- {
- /* close any old instances of this directory being open */
- #if 0
- dptr_closepath(directory,SVAL(inbuf,smb_pid));
- #endif
-
- dptr_num = dptr_create(Connections[cnum].dirptr,directory,
- expect_close,SVAL(inbuf,smb_pid));
- if (dptr_num < 0)
- {
- if(Connections[cnum].dirptr != NULL)
- closedir(Connections[cnum].dirptr);
- return(ERROR(ERRDOS,ERRnofids));
- }
- }
- }
-
- DEBUG(3,("dptr_num is %d\n",dptr_num));
-
- if (ok)
- {
- if ((dirtype&0x1F) == aVOLID)
- {
- memcpy(p,status,21);
- make_dir_struct(p,"???????????",SERVICE(SNUM(cnum)),0,aVOLID,0);
- dptr_fill(p+12,dptr_num);
- if (dptr_zero(p+12) && (status_len==0))
- numentries = 1;
- else
- numentries = 0;
- p += DIR_STRUCT_SIZE;
- }
- else
- {
- DEBUG(8,("dirpath=<%s> dontdescend=<%s>\n",Connections[cnum].dirpath,lp_dontdescend(SNUM(cnum))));
- if (in_list(Connections[cnum].dirpath,
- lp_dontdescend(SNUM(cnum)),True))
- check_descend = True;
-
- for (i=numentries;(i<maxentries) && !finished;i++)
- {
- finished =
- !get_dir_entry(cnum,mask,dirtype,fname,&size,&mode,&date,check_descend);
- if (!finished)
- {
- memcpy(p,status,21);
- make_dir_struct(p,mask,fname,size,mode,date);
- dptr_fill(p+12,dptr_num);
- numentries++;
- }
- p += DIR_STRUCT_SIZE;
- }
- }
- }
- }
- #if 1
- if ((numentries == 0 && status_len != 0) || !ok)
- #else
- if (finished || !ok)
- #endif
- {
- CVAL(outbuf,smb_rcls) = ERRDOS;
- SSVAL(outbuf,smb_err,ERRnofiles);
- if (dptr_num >= 0)
- dptr_demote(dptr_num);
- }
-
- /* If we were called as SMBffirst with smb_search_id == NULL
- and no entries were found then return error and close dirptr
- (X/Open spec) */
-
- if(ok && expect_close && numentries == 0 && status_len == 0)
- {
- CVAL(outbuf,smb_rcls) = ERRDOS;
- SSVAL(outbuf,smb_err,ERRnofiles);
- /* Also close the dptr - we know it's gone */
- dptr_demote(dptr_num);
- dptr_close(dptr_num);
- }
-
- /* If we were called as SMBfunique, then we can close the dirptr now ! */
- if(CVAL(inbuf,smb_com) == SMBfunique)
- {
- dptr_demote(dptr_num);
- dptr_close(dptr_num);
- }
-
- SSVAL(outbuf,smb_vwv0,numentries);
- SSVAL(outbuf,smb_vwv1,3 + numentries * DIR_STRUCT_SIZE);
- CVAL(smb_buf(outbuf),0) = 5;
- SSVAL(smb_buf(outbuf),1,numentries*DIR_STRUCT_SIZE);
-
- outsize += DIR_STRUCT_SIZE*numentries;
- smb_setlen(outbuf,outsize - 4);
-
- if ((! *directory) && dptr_path(dptr_num))
- sprintf(directory,"(%s)",dptr_path(dptr_num));
-
- DEBUG(4,("%s %s mask=%s directory=%s cnum=%d dirtype=%d numentries=%d\n",
- timestring(),
- smb_fn_name(CVAL(inbuf,smb_com)),
- mask,directory,cnum,dirtype,numentries));
-
- return(outsize);
- }
-
-
- /****************************************************************************
- reply to a fclose (stop directory search)
- ****************************************************************************/
- int reply_fclose(char *inbuf,char *outbuf)
- {
- int cnum;
- int outsize = 0;
- int status_len;
- char *path;
- char status[21];
- int dptr_num=-1;
-
- cnum = SVAL(inbuf,smb_tid);
-
- outsize = set_message(outbuf,1,0,True);
- path = smb_buf(inbuf) + 1;
- status_len = SVAL(smb_buf(inbuf),3 + strlen(path));
-
-
- if (status_len == 0)
- return(ERROR(ERRSRV,ERRsrverror));
-
- memcpy(status,smb_buf(inbuf) + 1 + strlen(path) + 4,21);
-
- if(!dptr_fetch(status+12,&dptr_num))
- return(ERROR(ERRSRV,ERRsrverror));
-
- /* Close the dptr - we know it's gone */
- dptr_demote(dptr_num);
- dptr_close(dptr_num);
-
- SSVAL(outbuf,smb_vwv0,0);
-
- DEBUG(3,("%s search close cnum=%d\n",timestring(),cnum));
-
- return(outsize);
- }
-
-
- /****************************************************************************
- reply to an open
- ****************************************************************************/
- int reply_open(char *inbuf,char *outbuf)
- {
- pstring fname="";
- int cnum;
- int fnum = -1;
- int outsize = 0;
- int mode,share,fmode=0,attribute;
- int openmode = 0;
- int size = 0;
- time_t mtime=0;
- int unixmode;
- int rmode;
- struct stat sbuf;
-
- cnum = SVAL(inbuf,smb_tid);
-
- share = SVAL(inbuf,smb_vwv0);
- mode = share & 0xF;
- #if 0
- attribute = SVAL(inbuf,smb_vwv1);
- #else
- /* X/Open says to ignore this */
- attribute = aARCH;
- #endif
- strcpy(fname,smb_buf(inbuf)+1);
- unix_convert(fname,cnum);
-
- rmode = mode;
-
- switch (mode)
- {
- case 0:
- openmode = O_RDONLY;
- break;
- case 1:
- openmode = O_WRONLY;
- break;
- case 0xF:
- mode = 2;
- case 2:
- openmode = O_RDWR;
- break;
- default:
- rmode = 0;
- openmode = O_RDONLY;
- break;
- }
-
- fnum = find_free_file();
- if (fnum < 0)
- return(ERROR(ERRSRV,ERRnofids));
-
- if (!check_name(fname,cnum))
- return(ERROR(ERRDOS,ERRnoaccess));
-
- unixmode = unix_mode(cnum,attribute);
-
- open_file(fnum,cnum,fname,openmode,unixmode);
-
- if (!Files[fnum].open)
- return(UNIXERROR(ERRDOS,ERRnoaccess));
-
- if (fstat(Files[fnum].fd,&sbuf) != 0)
- {
- close_file(fnum);
- return(ERROR(ERRDOS,ERRnoaccess));
- }
-
- size = sbuf.st_size;
- fmode = dos_mode(cnum,fname,&sbuf);
- mtime = sbuf.st_mtime;
-
- if (fmode & aDIR)
- {
- DEBUG(3,("attempt to open a directory %s\n",fname));
- close_file(fnum);
- return(ERROR(ERRDOS,ERRnoaccess));
- }
-
-
- outsize = set_message(outbuf,7,0,True);
- SSVAL(outbuf,smb_vwv0,fnum);
- SSVAL(outbuf,smb_vwv1,fmode);
- SIVAL(outbuf,smb_vwv2,mtime + GMT_TO_LOCAL * TimeDiff());
- SIVAL(outbuf,smb_vwv4,size);
- SSVAL(outbuf,smb_vwv6,rmode);
-
- DEBUG(2,("opened file %s for %s\n",fname,openmode==O_RDONLY?"reading":"writing"));
- DEBUG(3,("%s open %s fd=%d fnum=%d cnum=%d mode=%d omode=%d (numopen=%d)\n",timestring(),fname,Files[fnum].fd,fnum,cnum,mode,openmode,num_files_open));
-
- return(outsize);
- }
-
-
- /****************************************************************************
- reply to an open and X
- ****************************************************************************/
- int reply_open_and_X(char *inbuf,char *outbuf,int length,int bufsize)
- {
- pstring fname="";
- int cnum = SVAL(inbuf,smb_tid);
- int fnum = -1;
- int outsize = 0;
- int openmode = 0;
- int smb_com2 = CVAL(inbuf,smb_vwv0);
- int smb_off2 = SVAL(inbuf,smb_vwv1);
- int smb_mode = SVAL(inbuf,smb_vwv3);
- int smb_attr = SVAL(inbuf,smb_vwv5);
- #if 0
- int smb_flags = SVAL(inbuf,smb_vwv2);
- int smb_sattr = SVAL(inbuf,smb_vwv4);
- uint32 smb_time = IVAL(inbuf,smb_vwv6);
- #endif
- int smb_ofun = SVAL(inbuf,smb_vwv8);
- BOOL file_existed = False;
- int unixmode;
- int size=0,fmode=0,mtime=0,rmode;
- struct stat sbuf;
-
- /* XXXX we need to handle passed times, sattr and flags */
-
- strcpy(fname,smb_buf(inbuf));
- unix_convert(fname,cnum);
-
- rmode = smb_mode & 0x7;
-
- switch (smb_mode & 0x7)
- {
- case 0:
- openmode = O_RDONLY;
- break;
- case 1:
- openmode = O_WRONLY;
- break;
- case 0x7:
- case 2:
- rmode = 2;
- openmode = O_RDWR;
- break;
- case 3: /* map execute to read */
- openmode = O_RDONLY;
- break;
- default:
- rmode = 0;
- openmode = O_RDONLY;
- break;
- }
-
- /* now add create and trunc bits */
- if (smb_ofun & 0x10)
- openmode |= O_CREAT;
- if ((smb_ofun & 0x3) == 2)
- openmode |= O_TRUNC;
-
- fnum = find_free_file();
- if (fnum < 0)
- return(ERROR(ERRSRV,ERRnofids));
-
- if (!check_name(fname,cnum))
- return(ERROR(ERRDOS,ERRnoaccess));
-
- unixmode = unix_mode(cnum,smb_attr);
-
- file_existed = file_exist(fname);
-
- if ((smb_ofun & 0x3) == 0 && file_existed)
- return(ERROR(ERRDOS,ERRfilexists));
-
- open_file(fnum,cnum,fname,openmode,unixmode);
-
- if (!Files[fnum].open)
- return(UNIXERROR(ERRDOS,ERRnoaccess));
-
- if (fstat(Files[fnum].fd,&sbuf) != 0)
- {
- close_file(fnum);
- return(ERROR(ERRDOS,ERRnoaccess));
- }
-
- size = sbuf.st_size;
- fmode = dos_mode(cnum,fname,&sbuf);
- mtime = sbuf.st_mtime;
- if (fmode & aDIR)
- {
- close_file(fnum);
- return(ERROR(ERRDOS,ERRnoaccess));
- }
-
- outsize = set_message(outbuf,15,0,True);
- CVAL(outbuf,smb_vwv0) = smb_com2;
- SSVAL(outbuf,smb_vwv1,(chain_size+outsize)-4);
- SSVAL(outbuf,smb_vwv2,fnum);
- SSVAL(outbuf,smb_vwv3,fmode);
- SIVAL(outbuf,smb_vwv4,mtime + GMT_TO_LOCAL * TimeDiff());
- SIVAL(outbuf,smb_vwv6,size);
- SSVAL(outbuf,smb_vwv8,rmode);
-
- {
- int smb_action = 0;
-
- if (file_existed && !(openmode & O_TRUNC)) smb_action = 1;
- if (!file_existed) smb_action = 2;
- if (file_existed && (openmode & O_TRUNC)) smb_action = 3;
-
- /* if they requested a opportunistic lock and they have it read-only
- then tell them they have it - this is wrong but it might work */
- if ((CVAL(inbuf,smb_flg) & 0x20) && openmode == O_RDONLY)
- smb_action |= 0x8000;
-
- SSVAL(outbuf,smb_vwv11,smb_action);
- }
-
-
- DEBUG(2,("opened file %s for %s\n",fname,openmode==O_RDONLY?"reading":"writing"));
- DEBUG(2,("%s openX %s fd=%d fnum=%d cnum=%d mode=%d omode=%d (numopen=%d)\n",
- timestring(),fname,Files[fnum].fd,fnum,cnum,
- smb_mode,openmode,num_files_open));
-
- chain_fnum = fnum;
-
- if (smb_com2 != 0xFF)
- outsize += chain_reply(smb_com2,inbuf,inbuf+smb_off2+4,
- outbuf,outbuf+outsize,
- length,bufsize);
-
- chain_fnum = -1;
-
- return(outsize);
- }
-
-
- /****************************************************************************
- reply to a mknew
- ****************************************************************************/
- int reply_mknew(char *inbuf,char *outbuf)
- {
- pstring fname="";
- int cnum,com;
- int fnum = -1;
- int outsize = 0;
- int createmode;
- mode_t unixmode;
-
- com = SVAL(inbuf,smb_com);
- cnum = SVAL(inbuf,smb_tid);
-
- createmode = SVAL(inbuf,smb_vwv0);
- strcpy(fname,smb_buf(inbuf)+1);
- unix_convert(fname,cnum);
-
- if (createmode & aVOLID)
- {
- DEBUG(0,("Attempt to create file (%s) with volid set - please report this\n",fname));
- }
-
- unixmode = unix_mode(cnum,createmode);
-
- if (com == SMBmknew && file_exist(fname))
- return(ERROR(ERRDOS,ERRfilexists));
-
- fnum = find_free_file();
- if (fnum < 0)
- return(ERROR(ERRSRV,ERRnofids));
-
- if (!check_name(fname,cnum))
- return(ERROR(ERRDOS,ERRnoaccess));
-
- open_file(fnum,cnum,fname,O_RDWR | O_CREAT | O_TRUNC,unixmode);
-
- if (!Files[fnum].open)
- return(UNIXERROR(ERRDOS,ERRnoaccess));
-
- outsize = set_message(outbuf,1,0,True);
- SSVAL(outbuf,smb_vwv0,fnum);
-
- DEBUG(2,("new file %s\n",fname));
- DEBUG(3,("%s mknew %s fd=%d fnum=%d cnum=%d dmode=%d umode=%o\n",timestring(),fname,Files[fnum].fd,fnum,cnum,createmode,unixmode));
-
- return(outsize);
- }
-
-
- /****************************************************************************
- reply to a create temporary file
- ****************************************************************************/
- int reply_ctemp(char *inbuf,char *outbuf)
- {
- pstring fname="";
- pstring fname2="";
- int cnum;
- int fnum = -1;
- int outsize = 0;
- int createmode;
- mode_t unixmode;
-
- cnum = SVAL(inbuf,smb_tid);
- createmode = SVAL(inbuf,smb_vwv0);
- sprintf(fname,"%s/TMXXXXXX",smb_buf(inbuf)+1);
- unix_convert(fname,cnum);
-
- unixmode = unix_mode(cnum,createmode);
-
- fnum = find_free_file();
- if (fnum < 0)
- return(ERROR(ERRSRV,ERRnofids));
-
- if (!check_name(fname,cnum))
- return(ERROR(ERRDOS,ERRnoaccess));
-
- strcpy(fname2,(char *)mktemp(fname));
-
- open_file(fnum,cnum,fname2,O_RDWR | O_CREAT | O_TRUNC,unixmode);
-
- if (!Files[fnum].open)
- return(UNIXERROR(ERRDOS,ERRnoaccess));
-
- outsize = set_message(outbuf,1,2 + strlen(fname2),True);
- SSVAL(outbuf,smb_vwv0,fnum);
- CVAL(smb_buf(outbuf),0) = 4;
- strcpy(smb_buf(outbuf) + 1,fname2);
-
- DEBUG(2,("created temp file %s\n",fname2));
- DEBUG(3,("%s ctemp %s fd=%d fnum=%d cnum=%d dmode=%d umode=%o\n",timestring(),fname2,Files[fnum].fd,fnum,cnum,createmode,unixmode));
-
- return(outsize);
- }
-
-
- /****************************************************************************
- reply to a unlink
- ****************************************************************************/
- int reply_unlink(char *inbuf,char *outbuf)
- {
- int outsize = 0;
- pstring name="";
- BOOL isrootdir;
- int cnum;
- int dirtype;
- pstring directory="";
- pstring mask="";
- char *p;
- int count=0;
- int error = ERRnoaccess;
- BOOL rm_file;
- BOOL ok = False;
-
- cnum = SVAL(inbuf,smb_tid);
-
- dirtype = SVAL(inbuf,smb_vwv0);
-
- strcpy(name,smb_buf(inbuf) + 1);
-
- DEBUG(3,("reply_unlink : %s\n",name));
-
- unix_convert(name,cnum);
-
- p = strrchr(name,'/');
- if (!p)
- {
- strcpy(directory,"./");
- strcpy(mask,name);
- }
- else
- {
- *p = 0;
- strcpy(directory,name);
- strcpy(mask,p+1);
- }
-
- isrootdir = (strequal(directory,"./") ||
- strequal(directory,"."));
-
-
- {
- void *dirptr = NULL;
- struct DIRECT *dptr;
-
- if (check_name(directory,cnum))
- dirptr = (void *)opendir(directory);
-
- if (dirptr)
- {
- BOOL has_wild = (strchr(mask,'?') || strchr(mask,'*'));
- BOOL do_mangling;
-
- ok = True;
- error = ERRbadfile;
-
- while ((dptr = readdir(dirptr)))
- {
- pstring fname="";
- int fmode;
- rm_file = False; /* Set to true if we want to delete this file */
-
- strcpy(fname,dptr->d_name);
-
- do_mangling = ((has_wild || strchr(mask,magic_char)) &&
- lp_manglednames(SNUM(cnum)));
-
- /* We need to check the wildcard in different ways depending on
- whether long_filenames are needed in use. */
-
- if(!long_filenames)
- {
- if ((strcmp(fname,mask) == 0) ||
- (name_convert(fname,dptr->d_name,
- do_mangling,
- lp_mangled_map(SNUM(cnum))) &&
- mask_match(fname,mask,!isrootdir,False,False)))
- rm_file = True;
- }
- else /* Do Lanman2 wildcard matching */
- {
- if(lanman2_match(fname, mask, casesignames))
- rm_file = True;
- }
-
- if(rm_file)
- {
- struct stat sbuf;
- error = ERRnoaccess;
- sprintf(fname,"%s/%s",directory,dptr->d_name);
- if (stat(fname,&sbuf) != 0) continue;
- fmode = dos_mode(cnum,fname,&sbuf);
- if ((fmode & aDIR) != 0) continue;
- if ((fmode & aRONLY) != 0) continue;
- if (((fmode & ~dirtype) & (aHIDDEN | aSYSTEM)) != 0)
- continue;
- unlink(fname);
- DEBUG(3,("reply_unlink : doing unlink on %s\n",fname));
- count++;
- }
- }
- closedir(dirptr);
- }
- }
-
- if (!ok || count == 0)
- return(ERROR(ERRDOS,error));
-
- outsize = set_message(outbuf,0,0,True);
-
- return(outsize);
- }
-
-
- /****************************************************************************
- reply to a readbraw (core+ protocol)
- ****************************************************************************/
- int reply_readbraw(char *inbuf, char *outbuf)
- {
- extern int Client;
- int cnum,maxcount,mincount,timeout,fnum;
- BOOL nonblocking = False;
- int nread = 0;
- int ret=0, nwritten;
- int startpos;
- static char *read_buf=NULL;
- static int read_buf_size=0;
-
- cnum = SVAL(inbuf,smb_tid);
- fnum = GETFNUM(inbuf,smb_vwv0);
- if (!OPEN_FNUM(fnum))
- return(ERROR(ERRDOS,ERRbadfid));
-
- startpos = IVAL(inbuf,smb_vwv1);
- maxcount = SVAL(inbuf,smb_vwv3);
- mincount = SVAL(inbuf,smb_vwv4);
- timeout = IVALS(inbuf,smb_vwv5);
- if(timeout == 0)
- nonblocking = True;
-
- /* ensure we don't overrun the packet size */
- maxcount = MIN(65535,maxcount);
- maxcount = MAX(mincount,maxcount);
-
- if (!read_buf || read_buf_size < maxcount+8)
- {
- DEBUG(5,("expanding read_buf\n"));
- read_buf = (char *)Realloc(read_buf,maxcount+8);
- read_buf_size = maxcount+8;
- }
-
- if (!read_buf)
- DEBUG(0,("Out of memory in readbraw!\n"));
-
- {
- int toread = maxcount;
-
- if (OPEN_FNUM(fnum) && (Files[fnum].cnum == cnum))
- {
- if (!is_locked(fnum,cnum,toread,startpos))
- {
- nread = 0;
-
- if (toread > 0)
- {
- /* NOTE: We are ignoring mincount! */
- nread += read_file(fnum,
- &read_buf[4+nread],
- startpos+nread,
- toread, toread,
- (long)timeout,
- True);
- }
- }
- }
- }
-
- DEBUG(3,("%s readbraw fnum=%d cnum=%d start=%d max=%d min=%d timeout=%d nread=%d\n",
- timestring(),
- fnum,cnum,startpos,
- maxcount,mincount,timeout,nread));
-
- if (nread < 0)
- nread = 0; /* X/Open says not to return an error - just send a 0
- buffer back */
-
- /* Set up a return message and send it directly to the SMB redirector.
- Return -1 to signal no reply should be sent */
- /* Set up the Netbios message header */
- CVAL(read_buf,0) = 0;
- CVAL(read_buf,1) = 0;
-
- SSVAL(read_buf,2,nread);
- BSWP(read_buf+2,2);
-
- nread += 4; /* Include header */
- nwritten = 0;
-
- log_out(read_buf,nread);
-
- while (nwritten < nread)
- {
- ret = write_socket(Client,read_buf+nwritten,nread - nwritten);
- if (ret <= 0)
- {
- DEBUG(0,("Error writing %d bytes to client. %d. Exiting\n",nread-nwritten,ret));
- close_sockets();
- exit_server();
- }
- nwritten += ret;
- }
-
- DEBUG(5,("readbraw finished\n"));
- return -1;
- }
-
-
- /****************************************************************************
- reply to a lockread (core+ protocol)
- ****************************************************************************/
- int reply_lockread(char *inbuf,char *outbuf,int length,int bufsize)
- {
- int cnum,fnum;
- int nread = -1;
- char *data;
- int outsize = 0;
- uint32 startpos, numtoread;
- int eclass;
- uint32 ecode;
- BOOL ok = False;
-
- cnum = SVAL(inbuf,smb_tid);
- fnum = GETFNUM(inbuf,smb_vwv0);
- if (!OPEN_FNUM(fnum))
- return(ERROR(ERRDOS,ERRbadfid));
- if (Protocol >= PROTOCOL_LANMAN1)
- {
- if(HAS_CACHED_ERROR(fnum))
- return (CACHED_ERROR(fnum));
- }
- numtoread = SVAL(inbuf,smb_vwv1);
- startpos = IVAL(inbuf,smb_vwv2);
-
- outsize = set_message(outbuf,5,3,True);
- numtoread = MIN(bufsize-outsize,numtoread);
- data = smb_buf(outbuf) + 3;
-
- {
- if (OPEN_FNUM(fnum) && (Files[fnum].cnum == cnum))
- {
- if(!do_lock( fnum, cnum, numtoread, startpos, &eclass, &ecode))
- {
- return (ERROR(eclass,ecode));
- }
- nread = read_file(fnum,data,startpos,numtoread,numtoread,-1,False);
- ok = True;
- }
- }
-
- if ((nread < 0) || !ok)
- return(UNIXERROR(ERRDOS,ERRnoaccess));
-
- outsize += nread;
- SSVAL(outbuf,smb_vwv0,nread);
- SSVAL(outbuf,smb_vwv5,nread+3);
- SSVAL(smb_buf(outbuf),1,nread);
-
- DEBUG(3,("%s lockread fnum=%d cnum=%d num=%d nread=%d\n",timestring(),fnum,cnum,numtoread,nread));
-
- return(outsize);
- }
-
-
- /****************************************************************************
- reply to a read
- ****************************************************************************/
- int reply_read(char *inbuf,char *outbuf,int length,int bufsize)
- {
- int cnum,numtoread,fnum;
- int nread = -1;
- char *data;
- int startpos;
- int outsize = 0;
- BOOL ok = False;
-
- cnum = SVAL(inbuf,smb_tid);
- fnum = GETFNUM(inbuf,smb_vwv0);
- if (!OPEN_FNUM(fnum))
- return(ERROR(ERRDOS,ERRbadfid));
- if (Protocol >= PROTOCOL_LANMAN1)
- {
- if(HAS_CACHED_ERROR(fnum))
- return (CACHED_ERROR(fnum));
- }
- numtoread = SVAL(inbuf,smb_vwv1);
- startpos = IVAL(inbuf,smb_vwv2);
-
- outsize = set_message(outbuf,5,3,True);
- numtoread = MIN(bufsize-outsize,numtoread);
- data = smb_buf(outbuf) + 3;
-
- {
- if (OPEN_FNUM(fnum) && (Files[fnum].cnum == cnum))
- {
- if (is_locked(fnum,cnum,numtoread,startpos))
- return(ERROR(ERRDOS,ERRlock));
-
- nread = 0;
-
- if (numtoread > 0)
- {
- nread += read_file(fnum,data,
- startpos,
- numtoread,
- numtoread,
- -1,
- False);
- }
- ok = (nread >= 0);
- }
- }
-
-
- if ((nread < 0) || !ok)
- return(UNIXERROR(ERRDOS,ERRnoaccess));
-
- outsize += nread;
- SSVAL(outbuf,smb_vwv0,nread);
- SSVAL(outbuf,smb_vwv5,nread+3);
- SSVAL(smb_buf(outbuf),1,nread);
-
- DEBUG(3,("%s read fnum=%d cnum=%d num=%d nread=%d\n",timestring(),fnum,cnum,numtoread,nread));
-
- return(outsize);
- }
-
-
- /****************************************************************************
- reply to a read and X
- ****************************************************************************/
- int reply_read_and_X(char *inbuf,char *outbuf,int length,int bufsize)
- {
- int smb_com2 = CVAL(inbuf,smb_vwv0);
- int smb_off2 = SVAL(inbuf,smb_vwv1);
- int smb_fid = GETFNUM(inbuf,smb_vwv2);
- uint32 smb_offset = IVAL(inbuf,smb_vwv3);
- int smb_maxcnt = SVAL(inbuf,smb_vwv5);
- int smb_mincnt = SVAL(inbuf,smb_vwv6);
- #if 0
- uint32 smb_timeout = SVAL(inbuf,smb_vwv7);
- #endif
- int cnum;
- int nread = -1;
- char *data;
- int outsize = 0;
- BOOL ok = False;
-
- cnum = SVAL(inbuf,smb_tid);
-
- if (Protocol >= PROTOCOL_LANMAN1)
- {
- if(HAS_CACHED_ERROR(smb_fid))
- return (CACHED_ERROR(smb_fid));
- }
- outsize = set_message(outbuf,12,0,True);
- data = smb_buf(outbuf);
-
- {
- if (OPEN_FNUM(smb_fid) && (Files[smb_fid].cnum == cnum))
- {
- if (is_locked(smb_fid,cnum,smb_maxcnt,smb_offset))
- return(ERROR(ERRDOS,ERRlock));
- nread = read_file(smb_fid,data,smb_offset,smb_maxcnt,smb_maxcnt,-1,False);
- ok = True;
- }
- }
-
-
- if ((nread < 0) || !ok)
- return(UNIXERROR(ERRDOS,ERRnoaccess));
-
- outsize += nread;
- CVAL(outbuf,smb_vwv0) = smb_com2;
- SSVAL(outbuf,smb_vwv1,(outsize+chain_size)-4);
- SSVAL(outbuf,smb_vwv5,nread);
- SSVAL(outbuf,smb_vwv6,(int)(data - ((outbuf-chain_size)+4)));
- SSVAL(smb_buf(outbuf),-2,nread);
-
- DEBUG(3,("%s readX fnum=%d cnum=%d min=%d max=%d nread=%d com2=%d off2=%d\n",
- timestring(),smb_fid,cnum,
- smb_mincnt,smb_maxcnt,nread,smb_com2,smb_off2));
-
- chain_fnum = smb_fid;
-
- if (smb_com2 != 0xFF)
- outsize += chain_reply(smb_com2,inbuf,inbuf+smb_off2+4,
- outbuf,outbuf+outsize,
- length,bufsize);
-
- chain_fnum = -1;
-
- return(outsize);
- }
-
-
- /****************************************************************************
- reply to a writebraw (core+ or LANMAN1.0 protocol)
- ****************************************************************************/
- int reply_writebraw(char *inbuf,char *outbuf)
- {
- int nwritten=0;
- int total_written=0;
- int numtowrite=0;
- int cnum,fnum;
- int outsize = 0;
- long startpos, timeout;
- char *read_buf=NULL;
- char *data=NULL;
- BOOL ok = False;
- BOOL write_through;
-
- cnum = SVAL(inbuf,smb_tid);
- fnum = GETFNUM(inbuf,smb_vwv0);
-
- if (!OPEN_FNUM(fnum))
- return(ERROR(ERRDOS,ERRbadfid));
-
- if (Files[fnum].read_only)
- return(ERROR(ERRSRV,ERRaccess));
-
- if (Protocol >= PROTOCOL_LANMAN1)
- {
- if(HAS_CACHED_ERROR(fnum))
- return(CACHED_ERROR(fnum));
- }
-
- startpos = IVAL(inbuf,smb_vwv3);
- timeout = IVALS(inbuf,smb_vwv5);
- write_through = ((SVAL(inbuf,smb_vwv7) & 1) != 0);
-
- /* We have to deal with slightly different formats depending
- on whether we are using the core+ or lanman1.0 protocol */
- if(Protocol == PROTOCOL_COREPLUS) {
- numtowrite = SVAL(smb_buf(inbuf),-2);
- /* NB there is no length field here */
- data = smb_buf(inbuf);
- } else { /* LANMAN1.0 Protocol */
- numtowrite = SVAL(inbuf,smb_vwv10);
- data = inbuf + 4 + SVAL(inbuf, smb_vwv11);
- }
-
- {
- extern int Client;
- if (OPEN_FNUM(fnum) && (Files[fnum].cnum == cnum))
- {
- if (is_locked(fnum,cnum,numtowrite,startpos))
- return(ERROR(ERRDOS,ERRlock));
-
- if (seek_file(fnum,startpos) != startpos)
- DEBUG(0,("couldn't seek to %d in writebraw\n",startpos));
-
- if (numtowrite>0)
- nwritten = write_with_timeout(Files[fnum].fd,
- data,numtowrite,
- timeout);
- #ifndef NO_FSYNC
- if(write_through)
- fsync(Files[fnum].fd);
- #endif
-
- ok = True;
-
- DEBUG(3,("%s writebraw message 1 fnum=%d cnum=%d start=%d num=%d wrote=%d\n",
- timestring(),fnum,cnum,startpos,numtowrite,nwritten));
- DEBUG(5,("writethrough=%d\n",write_through));
-
- if ((nwritten < numtowrite) || !ok)
- return(UNIXERROR(ERRDOS,ERRnoaccess));
-
- total_written = nwritten;
-
- /* Return a message to the redirector to tell it
- to send more bytes */
- CVAL(outbuf,smb_com) = SMBwritebraw;
-
- if(Protocol <= PROTOCOL_COREPLUS) {
- outsize = set_message(outbuf,0,0,True);
- } else { /* LANMAN1.0 Protocol */
- outsize = set_message(outbuf,1,0,True);
- SSVALS(outbuf,smb_vwv0,-1); /* We don't support smb_remaining */
- }
- smb_setlen(outbuf, outsize-4);
- send_smb(outbuf);
-
- /* Now read the raw data into the buffer and write it */
- if(read_smb_length(Client,inbuf,0) == -1) {
- DEBUG(0,("Failed to read length of secondary writebraw\n"));
- close_sockets();
- exit_server();
- }
-
- /* Even though this is not an smb message, smb_len
- returns the generic length of an smb message */
- numtowrite = smb_len(inbuf);
- if (numtowrite > 0)
- {
- read_buf = (char *)malloc(numtowrite + SAFETY_MARGIN);
- if (!read_buf)
- DEBUG(0,("Out of memory in writebraw!\n"));
-
- if(!read_data(Client,read_buf,numtowrite)) {
- DEBUG(0,("Failed to read data in secondary writebraw\n"));
- close_sockets();
- exit_server();
- }
-
-
- if (is_locked(fnum,cnum,numtowrite,startpos + total_written))
- return(ERROR(ERRDOS,ERRlock));
-
- nwritten = write_with_timeout(Files[fnum].fd,
- read_buf,numtowrite,
- timeout);
- if (read_buf) free(read_buf);
-
- total_written += nwritten;
- }
-
- #ifndef NO_FSYNC
- if(write_through)
- fsync(Files[fnum].fd);
- #endif
- DEBUG(5,("writethrough=%d\n",write_through));
-
- ok = True;
-
- /* Set up outbuf to return the correct return */
- outsize = set_message(outbuf,1,0,True);
- CVAL(outbuf,smb_com) = SMBwritec;
- SSVAL(outbuf,smb_vwv0,total_written);
- }
- }
-
- DEBUG(3,("%s writebraw extra fnum=%d cnum=%d start=%d num=%d wrote=%d\n",
- timestring(),fnum,cnum,startpos,numtowrite,total_written));
-
- return(outsize);
- }
-
-
- /****************************************************************************
- reply to a writeunlock (core+)
- ****************************************************************************/
- int reply_writeunlock(char *inbuf,char *outbuf)
- {
- int cnum,fnum;
- int nwritten = -1;
- int outsize = 0;
- int fd;
- char *data;
- uint32 numtowrite,startpos;
- int eclass;
- uint32 ecode;
- BOOL ok = False;
-
- cnum = SVAL(inbuf,smb_tid);
- fnum = GETFNUM(inbuf,smb_vwv0);
- if (!OPEN_FNUM(fnum))
- return(ERROR(ERRDOS,ERRbadfid));
-
- if (Files[fnum].read_only)
- return(ERROR(ERRSRV,ERRaccess));
-
- if (Protocol >= PROTOCOL_LANMAN1)
- {
- if(HAS_CACHED_ERROR(fnum))
- return (CACHED_ERROR(fnum));
- }
- numtowrite = SVAL(inbuf,smb_vwv1);
- startpos = IVAL(inbuf,smb_vwv2);
- data = smb_buf(inbuf) + 3;
-
- fd = Files[fnum].fd;
-
- if (OPEN_FNUM(fnum) && (Files[fnum].cnum == cnum))
- {
- if (is_locked(fnum,cnum,numtowrite,startpos))
- return(ERROR(ERRDOS,ERRlock));
-
- seek_file(fnum,startpos);
-
- /* The special X/Open SMB protocol handling of
- zero length writes is *NOT* done for
- this call */
- if(numtowrite == 0)
- nwritten = 0;
- else
- nwritten = write(fd,data,numtowrite);
- ok = True;
- }
-
- if(((nwritten == 0) && (numtowrite != 0))||(nwritten < 0) || !ok)
- return(UNIXERROR(ERRDOS,ERRnoaccess));
-
- if(!do_unlock(fnum, cnum, numtowrite, startpos, &eclass, &ecode))
- return(ERROR(eclass,ecode));
-
- outsize = set_message(outbuf,1,0,True);
-
- SSVAL(outbuf,smb_vwv0,nwritten);
-
- DEBUG(3,("%s writeunlock fnum=%d cnum=%d num=%d wrote=%d\n",timestring(),fnum,cnum,numtowrite,nwritten));
-
- return(outsize);
- }
-
-
- /****************************************************************************
- reply to a write
- ****************************************************************************/
- int reply_write(char *inbuf,char *outbuf)
- {
- int cnum,numtowrite,fnum;
- int nwritten = -1;
- int outsize = 0;
- int startpos;
- int fd;
- char *data;
- BOOL ok = False;
-
- cnum = SVAL(inbuf,smb_tid);
- fnum = GETFNUM(inbuf,smb_vwv0);
-
- if (!OPEN_FNUM(fnum))
- return(ERROR(ERRDOS,ERRbadfid));
-
- if (Files[fnum].read_only)
- return(ERROR(ERRSRV,ERRaccess));
-
- if (Protocol >= PROTOCOL_LANMAN1)
- {
- if(HAS_CACHED_ERROR(fnum))
- return (CACHED_ERROR(fnum));
- }
- numtowrite = SVAL(inbuf,smb_vwv1);
- startpos = IVAL(inbuf,smb_vwv2);
- data = smb_buf(inbuf) + 3;
-
- fd = Files[fnum].fd;
-
- if (OPEN_FNUM(fnum) && (Files[fnum].cnum == cnum))
- {
- if (is_locked(fnum,cnum,numtowrite,startpos))
- return(ERROR(ERRDOS,ERRlock));
-
- seek_file(fnum,startpos);
-
- /* X/Open SMB protocol says that if smb_vwv1 is
- zero then the file size should be extended or
- truncated to the size given in smb_vwv[2-3] */
- if(numtowrite == 0)
- nwritten = set_filelen(fd, startpos);
- else
- nwritten = write(fd,data,numtowrite);
- ok = True;
- }
-
- if(((nwritten == 0) && (numtowrite != 0))||(nwritten < 0) || !ok)
- return(UNIXERROR(ERRDOS,ERRnoaccess));
-
- outsize = set_message(outbuf,1,0,True);
-
- SSVAL(outbuf,smb_vwv0,nwritten);
-
- DEBUG(3,("%s write fnum=%d cnum=%d num=%d wrote=%d\n",timestring(),fnum,cnum,numtowrite,nwritten));
-
- return(outsize);
- }
-
-
- /****************************************************************************
- reply to a write and X
- ****************************************************************************/
- int reply_write_and_X(char *inbuf,char *outbuf,int length,int bufsize)
- {
- int smb_com2 = CVAL(inbuf,smb_vwv0);
- int smb_off2 = SVAL(inbuf,smb_vwv1);
- int fnum = GETFNUM(inbuf,smb_vwv2);
- uint32 smb_offset = IVAL(inbuf,smb_vwv3);
- int smb_dsize = SVAL(inbuf,smb_vwv10);
- int smb_doff = SVAL(inbuf,smb_vwv11);
-
- int cnum;
- int nwritten = -1;
- int outsize = 0;
- int fd;
- char *data;
- BOOL ok = False;
-
- cnum = SVAL(inbuf,smb_tid);
-
- if (!OPEN_FNUM(fnum))
- return(ERROR(ERRDOS,ERRbadfid));
-
- if (Files[fnum].read_only)
- return(ERROR(ERRSRV,ERRaccess));
-
- if (Protocol >= PROTOCOL_LANMAN1)
- {
- if(HAS_CACHED_ERROR(fnum))
- return (CACHED_ERROR(fnum));
- }
-
- data = inbuf + 4 + smb_doff;
-
- fd = Files[fnum].fd;
-
- if (OPEN_FNUM(fnum) && (Files[fnum].cnum == cnum))
- {
- if (is_locked(fnum,cnum,smb_dsize,smb_offset))
- return(ERROR(ERRDOS,ERRlock));
-
- seek_file(fnum,smb_offset);
-
- /* X/Open SMB protocol says that, unlike SMBwrite
- if the length is zero then NO truncation is
- done, just a write of zero. To truncate a file,
- use SMBwrite. */
- if(smb_dsize == 0)
- nwritten = 0;
- else
- nwritten = write(fd,data,smb_dsize);
- ok = True;
- }
-
- if(((nwritten == 0) && (smb_dsize != 0))||(nwritten < 0) || !ok)
- return(UNIXERROR(ERRDOS,ERRnoaccess));
-
- outsize = set_message(outbuf,6,0,True);
-
- CVAL(outbuf,smb_vwv0) = smb_com2;
- SSVAL(outbuf,smb_vwv1,(outsize+chain_size)-4);
- SSVAL(outbuf,smb_vwv2,nwritten);
-
- DEBUG(3,("%s writeX fnum=%d cnum=%d num=%d wrote=%d\n",timestring(),fnum,cnum,smb_dsize,nwritten));
-
- chain_fnum = fnum;
-
- if (smb_com2 != 0xFF)
- outsize += chain_reply(smb_com2,inbuf,inbuf+smb_off2+4,
- outbuf,outbuf+outsize,
- length,bufsize);
-
- chain_fnum = -1;
-
- return(outsize);
- }
-
-
- /****************************************************************************
- reply to a lseek
- ****************************************************************************/
- int reply_lseek(char *inbuf,char *outbuf)
- {
- int cnum,fnum;
- uint32 startpos;
- int32 res=-1;
- int mode;
- int outsize = 0;
- BOOL ok = False;
-
- cnum = SVAL(inbuf,smb_tid);
- fnum = GETFNUM(inbuf,smb_vwv0);
- if (!OPEN_FNUM(fnum))
- return(ERROR(ERRDOS,ERRbadfid));
- if (Protocol >= PROTOCOL_LANMAN1)
- {
- if(HAS_CACHED_ERROR(fnum))
- return (CACHED_ERROR(fnum));
- }
- mode = SVAL(inbuf,smb_vwv1);
- startpos = IVAL(inbuf,smb_vwv2);
-
- {
- if (OPEN_FNUM(fnum) && (Files[fnum].cnum == cnum))
- {
- res = lseek(Files[fnum].fd,startpos,mode);
- Files[fnum].pos = -1;
- }
- ok = True;
- }
-
-
- if ((res < 0) || !ok)
- return(UNIXERROR(ERRDOS,ERRnoaccess));
-
- outsize = set_message(outbuf,2,0,True);
- SIVAL(outbuf,smb_vwv0,res);
-
- DEBUG(3,("%s lseek fnum=%d cnum=%d pos=%d\n",timestring(),fnum,cnum,startpos));
-
- return(outsize);
- }
-
-
- /****************************************************************************
- reply to a flush
- ****************************************************************************/
- int reply_flush(char *inbuf,char *outbuf)
- {
- int cnum, fnum;
- int outsize = set_message(outbuf,0,0,True);
-
- cnum = SVAL(inbuf,smb_tid);
- fnum = GETFNUM(inbuf,smb_vwv0);
- if (Protocol >= PROTOCOL_LANMAN1 && OPEN_FNUM(fnum))
- {
- if(HAS_CACHED_ERROR(fnum))
- return (CACHED_ERROR(fnum));
- }
-
- #ifndef NO_FSYNC
- if (fnum == 0xFFFF)
- {
- int i;
- for (i=0;i<MAX_OPEN_FILES;i++)
- if (OPEN_FNUM(i))
- fsync(Files[i].fd);
- }
- else
- {
- if (OPEN_FNUM(fnum))
- fsync(Files[fnum].fd);
- }
- #endif
-
- DEBUG(3,("%s flush fnum=%d\n",timestring(),fnum));
- return(outsize);
- }
-
-
- /****************************************************************************
- reply to a exit
- ****************************************************************************/
- int reply_exit(char *inbuf,char *outbuf)
- {
- int outsize = set_message(outbuf,0,0,True);
- DEBUG(3,("%s exit\n",timestring()));
-
- return(outsize);
- }
-
-
- /****************************************************************************
- reply to a close
- ****************************************************************************/
- int reply_close(char *inbuf,char *outbuf)
- {
- int fnum,cnum;
- int outsize = 0;
- BOOL ok = False;
- time_t mtime;
- int32 eclass = 0, err = 0;
-
- outsize = set_message(outbuf,0,0,True);
-
- cnum = SVAL(inbuf,smb_tid);
-
- fnum = GETFNUM(inbuf,smb_vwv0);
- if (!OPEN_FNUM(fnum))
- return(ERROR(ERRDOS,ERRbadfid));
-
- if (Protocol >= PROTOCOL_LANMAN1)
- {
- /* Make sure we have done the close first */
- if(HAS_CACHED_ERROR(fnum))
- {
- eclass = Files[fnum].wbmpx_ptr->wr_errclass;
- err = Files[fnum].wbmpx_ptr->wr_error;
- }
- }
- mtime = IVAL(inbuf,smb_vwv1);
-
- {
- if (OPEN_FNUM(fnum) && (Files[fnum].cnum == cnum))
- {
- close_file(fnum);
-
- /* try and set the date */
- if (mtime == 0 || mtime == -1)
- DEBUG(5,("not setting null date\n"));
- else
- set_filetime(Files[fnum].name,mtime + LOCAL_TO_GMT * TimeDiff());
-
- ok = True;
- }
- }
-
- /* We have a cached error */
- if(eclass || err)
- return(ERROR(eclass,err));
-
- if (!ok)
- return(UNIXERROR(ERRDOS,ERRnoaccess));
-
-
- DEBUG(3,("%s close fd=%d fnum=%d cnum=%d (numopen=%d)\n",
- timestring(),Files[fnum].fd,fnum,cnum,num_files_open));
-
- return(outsize);
- }
-
-
- /****************************************************************************
- reply to a writeclose (Core+ protocol)
- ****************************************************************************/
- int reply_writeclose(char *inbuf,char *outbuf)
- {
- int cnum,numtowrite,fnum;
- int nwritten = -1;
- int outsize = 0;
- int startpos;
- char *data;
- time_t mtime;
- BOOL ok = False;
-
- cnum = SVAL(inbuf,smb_tid);
- fnum = GETFNUM(inbuf,smb_vwv0);
-
- if (!OPEN_FNUM(fnum))
- return(ERROR(ERRDOS,ERRbadfid));
-
- if (Files[fnum].read_only)
- return(ERROR(ERRSRV,ERRaccess));
-
- if (Protocol >= PROTOCOL_LANMAN1)
- {
- if(HAS_CACHED_ERROR(fnum))
- return (CACHED_ERROR(fnum));
- }
- numtowrite = SVAL(inbuf,smb_vwv1);
- startpos = IVAL(inbuf,smb_vwv2);
- mtime = IVAL(inbuf,smb_vwv4);
- data = smb_buf(inbuf) + 1;
-
- if (OPEN_FNUM(fnum) && (Files[fnum].cnum == cnum))
- {
- if (is_locked(fnum,cnum,numtowrite,startpos))
- return(ERROR(ERRDOS,ERRlock));
-
- seek_file(fnum,startpos);
-
- nwritten = write(Files[fnum].fd,data,numtowrite);
- ok = True;
-
- close_file(fnum);
-
- if (mtime == 0 || mtime == -1)
- DEBUG(5,("not setting null date\n"));
- else
- set_filetime(Files[fnum].name,mtime + LOCAL_TO_GMT * TimeDiff());
- }
-
- DEBUG(3,("%s writeclose fnum=%d cnum=%d num=%d wrote=%d (numopen=%d)\n",
- timestring(),fnum,cnum,numtowrite,nwritten,num_files_open));
-
- if ((nwritten <= 0) || !ok)
- return(UNIXERROR(ERRDOS,ERRnoaccess));
-
- outsize = set_message(outbuf,1,0,True);
-
- SSVAL(outbuf,smb_vwv0,nwritten);
- return(outsize);
- }
-
-
- /****************************************************************************
- reply to a lock
- ****************************************************************************/
- int reply_lock(char *inbuf,char *outbuf)
- {
- int fnum,cnum;
- int outsize = set_message(outbuf,0,0,True);
- uint32 count,offset;
- int eclass;
- uint32 ecode;
-
- cnum = SVAL(inbuf,smb_tid);
- fnum = GETFNUM(inbuf,smb_vwv0);
- if (!OPEN_FNUM(fnum))
- return(ERROR(ERRDOS,ERRbadfid));
- if (Protocol >= PROTOCOL_LANMAN1)
- {
- if(HAS_CACHED_ERROR(fnum))
- return (CACHED_ERROR(fnum));
- }
-
- count = IVAL(inbuf,smb_vwv1);
- offset = IVAL(inbuf,smb_vwv3);
-
- DEBUG(3,("%s lock fd=%d fnum=%d cnum=%d ofs=%d cnt=%d\n",timestring(),Files[fnum].fd,fnum,cnum,offset,count));
-
- if(!do_lock( fnum, cnum, count, offset, &eclass, &ecode))
- return (ERROR(eclass,ecode));
-
- return(outsize);
- }
-
-
- /****************************************************************************
- reply to a unlock
- ****************************************************************************/
- int reply_unlock(char *inbuf,char *outbuf)
- {
- int fnum,cnum;
- int outsize = set_message(outbuf,0,0,True);
- uint32 count,offset;
- int eclass;
- uint32 ecode;
-
- cnum = SVAL(inbuf,smb_tid);
- fnum = GETFNUM(inbuf,smb_vwv0);
- if (!OPEN_FNUM(fnum))
- return(ERROR(ERRDOS,ERRbadfid));
- if (Protocol >= PROTOCOL_LANMAN1)
- {
- if(HAS_CACHED_ERROR(fnum))
- return (CACHED_ERROR(fnum));
- }
-
- count = IVAL(inbuf,smb_vwv1);
- offset = IVAL(inbuf,smb_vwv3);
-
- if(!do_unlock(fnum, cnum, count, offset, &eclass, &ecode))
- return (ERROR(eclass,ecode));
-
- DEBUG(3,("%s unlock fd=%d fnum=%d cnum=%d ofs=%d cnt=%d\n",timestring(),Files[fnum].fd,fnum,cnum,offset,count));
-
- return(outsize);
- }
-
-
- /****************************************************************************
- reply to a tdis
- ****************************************************************************/
- int reply_tdis(char *inbuf,char *outbuf)
- {
- int cnum;
- int outsize = set_message(outbuf,0,0,True);
-
- cnum = SVAL(inbuf,smb_tid);
-
- close_cnum(cnum);
-
- DEBUG(3,("%s tdis cnum=%d\n",timestring(),cnum));
-
- return outsize;
- }
-
-
- /****************************************************************************
- reply to a echo
- ****************************************************************************/
- int reply_echo(char *inbuf,char *outbuf)
- {
- int cnum;
- int smb_reverb = SVAL(inbuf,smb_vwv0);
- int seq_num;
- int data_len = smb_buflen(inbuf);
- int outsize = set_message(outbuf,1,data_len,True);
-
- cnum = SVAL(inbuf,smb_tid);
-
- if (cnum != 0xFFFF && !OPEN_CNUM(cnum))
- {
- DEBUG(4,("Invalid cnum in echo (%d)\n",cnum));
- return(ERROR(ERRSRV,ERRinvnid));
- }
-
- /* copy any incoming data back out */
- if (data_len > 0)
- memcpy(smb_buf(outbuf),smb_buf(inbuf),data_len);
-
- if (smb_reverb > 100)
- {
- DEBUG(0,("large reverb (%d)?? Setting to 100\n",smb_reverb));
- smb_reverb = 100;
- }
-
- for (seq_num =1 ; seq_num <= smb_reverb ; seq_num++)
- {
- SSVAL(outbuf,smb_vwv0,seq_num);
-
- smb_setlen(outbuf,outsize - 4);
-
- send_smb(outbuf);
- }
-
- DEBUG(3,("%s echo %d times cnum=%d\n",timestring(),smb_reverb,cnum));
-
- return -1;
- }
-
-
- /****************************************************************************
- reply to a printopen
- ****************************************************************************/
- int reply_printopen(char *inbuf,char *outbuf)
- {
- pstring fname="";
- pstring fname2="";
- int cnum;
- int fnum = -1;
- int outsize = 0;
-
- cnum = SVAL(inbuf,smb_tid);
-
- if (!CAN_PRINT(cnum))
- return(ERROR(ERRDOS,ERRnoaccess));
-
- {
- pstring s;
- char *p;
- StrnCpy(s,smb_buf(inbuf)+1,sizeof(pstring)-1);
- p = s;
- while (*p)
- {
- if (!(isalnum(*p) || strchr("._-",*p)))
- *p = 'X';
- p++;
- }
-
- if (strlen(s) > 6) s[6] = 0;
-
- sprintf(fname,"%s.XXXXXX",s);
- }
-
- fnum = find_free_file();
- if (fnum < 0)
- return(ERROR(ERRSRV,ERRnofids));
-
- strcpy(fname2,(char *)mktemp(fname));
-
- if (!check_name(fname2,cnum))
- return(ERROR(ERRDOS,ERRnoaccess));
-
- open_file(fnum,cnum,fname2,O_WRONLY | O_CREAT | O_TRUNC,
- unix_mode(cnum,0));
-
- if (!Files[fnum].open)
- return(UNIXERROR(ERRDOS,ERRnoaccess));
-
- /* force it to be a print file */
- Files[fnum].print_file = True;
-
- outsize = set_message(outbuf,1,0,True);
- SSVAL(outbuf,smb_vwv0,fnum);
-
- DEBUG(3,("%s openprint %s fd=%d fnum=%d cnum=%d\n",timestring(),fname2,Files[fnum].fd,fnum,cnum));
-
- return(outsize);
- }
-
-
- /****************************************************************************
- reply to a printclose
- ****************************************************************************/
- int reply_printclose(char *inbuf,char *outbuf)
- {
- int fnum,cnum;
- int outsize = set_message(outbuf,0,0,True);
-
- cnum = SVAL(inbuf,smb_tid);
- fnum = GETFNUM(inbuf,smb_vwv0);
- if (!OPEN_FNUM(fnum))
- return(ERROR(ERRDOS,ERRbadfid));
- if (Protocol >= PROTOCOL_LANMAN1)
- {
- if(HAS_CACHED_ERROR(fnum))
- return (CACHED_ERROR(fnum));
- }
-
- if (!CAN_PRINT(cnum))
- return(ERROR(ERRDOS,ERRnoaccess));
-
- if (OPEN_FNUM(fnum) && (Files[fnum].cnum == cnum))
- close_file(fnum);
-
- DEBUG(3,("%s printclose fd=%d fnum=%d cnum=%d\n",timestring(),Files[fnum].fd,fnum,cnum));
-
- return(outsize);
- }
-
-
- /****************************************************************************
- reply to a printqueue
- ****************************************************************************/
- int reply_printqueue(char *inbuf,char *outbuf)
- {
- int cnum;
- int outsize = set_message(outbuf,2,3,True);
- int max_count = SVAL(inbuf,smb_vwv0);
- int start_index = SVAL(inbuf,smb_vwv1);
-
- cnum = SVAL(inbuf,smb_tid);
-
- /* allow checking the queue for anyone */
- #if 0
- if (!CAN_PRINT(cnum))
- return(ERROR(ERRDOS,ERRnoaccess));
- #endif
-
- SSVAL(outbuf,smb_vwv0,0);
- SSVAL(outbuf,smb_vwv1,0);
- CVAL(smb_buf(outbuf),0) = 1;
- SSVAL(smb_buf(outbuf),1,0);
-
- DEBUG(3,("%s printqueue cnum=%d start_index=%d max_count=%d\n",
- timestring(),cnum,start_index,max_count));
-
- if (!OPEN_CNUM(cnum) || !Connections[cnum].printer)
- {
- int i;
- cnum = -1;
-
- for (i=0;i<MAX_CONNECTIONS;i++)
- if (CAN_PRINT(i) && Connections[i].printer)
- cnum = i;
-
- if (cnum == -1)
- for (i=0;i<MAX_CONNECTIONS;i++)
- if (OPEN_CNUM(i))
- cnum = i;
-
- if (!OPEN_CNUM(cnum))
- return(ERROR(ERRSRV,ERRinvnid));
-
- DEBUG(5,("connection not open or not a printer, using cnum %d\n",cnum));
- }
-
- if (!become_user(cnum))
- return(ERROR(ERRSRV,ERRinvnid));
-
- {
- print_queue_struct *queue = NULL;
- char *p = smb_buf(outbuf) + 3;
- int count = get_printqueue(SNUM(cnum),&queue);
- int num_to_get = ABS(max_count);
- int first = (max_count>0?start_index:start_index+max_count+1);
- int i;
-
- if (first >= count)
- num_to_get = 0;
- else
- num_to_get = MIN(num_to_get,count-first);
-
-
- for (i=first;i<first+num_to_get;i++)
- {
- put_dos_date2(p,0,queue[i].time);
- CVAL(p,4) = (queue[i].status==LPQ_PRINTING?2:3);
- SSVAL(p,5,queue[i].job);
- SIVAL(p,7,queue[i].size);
- CVAL(p,11) = 0;
- StrnCpy(p+12,queue[i].user,16);
- p += 28;
- }
-
- if (count > 0)
- {
- outsize = set_message(outbuf,2,28*count+3,False);
- SSVAL(outbuf,smb_vwv0,count);
- SSVAL(outbuf,smb_vwv1,(max_count>0?first+count:first-1));
- CVAL(smb_buf(outbuf),0) = 1;
- SSVAL(smb_buf(outbuf),1,28*count);
- }
-
- if (queue) free(queue);
-
- DEBUG(3,("%d entries returned in queue\n",count));
- }
-
- return(outsize);
- }
-
-
- /****************************************************************************
- reply to a printwrite
- ****************************************************************************/
- int reply_printwrite(char *inbuf,char *outbuf)
- {
- int cnum,numtowrite,fnum;
- int outsize = set_message(outbuf,0,0,True);
- char *data;
- BOOL ok = False;
-
- cnum = SVAL(inbuf,smb_tid);
-
- if (!CAN_PRINT(cnum))
- return(ERROR(ERRDOS,ERRnoaccess));
-
- fnum = GETFNUM(inbuf,smb_vwv0);
-
- if (!OPEN_FNUM(fnum))
- return(ERROR(ERRDOS,ERRbadfid));
-
- if (Files[fnum].read_only)
- return(ERROR(ERRSRV,ERRaccess));
-
- if (Protocol >= PROTOCOL_LANMAN1)
- {
- if(HAS_CACHED_ERROR(fnum))
- return (CACHED_ERROR(fnum));
- }
-
- numtowrite = SVAL(smb_buf(inbuf),1);
- data = smb_buf(inbuf) + 3;
-
- if (OPEN_FNUM(fnum) && (Files[fnum].cnum == cnum))
- ok = (write(Files[fnum].fd,data,numtowrite) == numtowrite);
-
- if (!ok)
- return(UNIXERROR(ERRDOS,ERRnoaccess));
-
- DEBUG(3,("%s printwrite fnum=%d cnum=%d num=%d\n",timestring(),fnum,cnum,numtowrite));
-
- return(outsize);
- }
-
-
- /****************************************************************************
- reply to a mkdir
- ****************************************************************************/
- int reply_mkdir(char *inbuf,char *outbuf)
- {
- pstring directory="";
- int cnum;
- int outsize,ret=-1;
-
- strcpy(directory,smb_buf(inbuf) + 1);
- cnum = SVAL(inbuf,smb_tid);
- unix_convert(directory,cnum);
-
- if (check_name(directory,cnum))
- ret = mkdir(directory,unix_mode(cnum,aDIR));
-
- if (ret < 0)
- return(UNIXERROR(ERRDOS,ERRnoaccess));
-
- outsize = set_message(outbuf,0,0,True);
-
- DEBUG(3,("%s mkdir %s cnum=%d ret=%d\n",timestring(),directory,cnum,ret));
-
- return(outsize);
- }
-
-
- /****************************************************************************
- reply to a rmdir
- ****************************************************************************/
- int reply_rmdir(char *inbuf,char *outbuf)
- {
- pstring directory="";
- int cnum;
- int outsize = 0;
- BOOL ok = False;
-
- cnum = SVAL(inbuf,smb_tid);
- strcpy(directory,smb_buf(inbuf) + 1);
- unix_convert(directory,cnum);
-
- if (check_name(directory,cnum))
- {
- dptr_closepath(directory,SVAL(inbuf,smb_pid));
- ok = (rmdir(directory) == 0);
- if (!ok)
- DEBUG(3,("couldn't remove directory %s : %s\n",
- directory,strerror(errno)));
- }
-
- if (!ok)
- return(UNIXERROR(ERRDOS,ERRbadpath));
-
- outsize = set_message(outbuf,0,0,True);
-
- DEBUG(3,("%s rmdir %s\n",timestring(),directory));
-
- return(outsize);
- }
-
-
- /****************************************************************************
- reply to a mv
- ****************************************************************************/
- int reply_mv(char *inbuf,char *outbuf)
- {
- pstring oldname="";
- pstring newname="";
- int cnum;
- int outsize = 0;
- BOOL ok = False;
-
- strcpy(oldname,smb_buf(inbuf) + 1);
- strcpy(newname,smb_buf(inbuf) + 3 + strlen(oldname));
-
- cnum = SVAL(inbuf,smb_tid);
- unix_convert(oldname,cnum);
- unix_convert(newname,cnum);
-
- if (check_name(oldname,cnum) && check_name(newname,cnum))
- ok = (rename(oldname,newname) == 0);
-
- if (!ok)
- return(UNIXERROR(ERRDOS,ERRnoaccess));
-
- outsize = set_message(outbuf,0,0,True);
-
- DEBUG(3,("%s mv %s to %s cnum=%d\n",timestring(),oldname,newname,cnum));
-
- return(outsize);
- }
-
-
- /****************************************************************************
- reply to a setdir
- ****************************************************************************/
- int reply_setdir(char *inbuf,char *outbuf)
- {
- int cnum,snum;
- int outsize = 0;
- BOOL ok = False;
- pstring newdir="";
-
- cnum = SVAL(inbuf,smb_tid);
-
- snum = Connections[cnum].service;
- if (!CAN_SETDIR(snum))
- return(ERROR(ERRDOS,ERRnoaccess));
-
- strcpy(newdir,smb_buf(inbuf) + 1);
- strlower(newdir);
-
- if (strlen(newdir) == 0)
- ok = True;
- else
- {
- ok = directory_exist(newdir);
- if (ok)
- strcpy(Connections[cnum].connectpath,newdir);
- }
-
- if (!ok)
- return(ERROR(ERRDOS,ERRbadpath));
-
- outsize = set_message(outbuf,0,0,True);
- CVAL(outbuf,smb_reh) = CVAL(inbuf,smb_reh);
-
- DEBUG(3,("%s setdir %s cnum=%d\n",timestring(),newdir,cnum));
-
- return(outsize);
- }
-
-
- /****************************************************************************
- reply to a lockingX request
- ****************************************************************************/
- int reply_lockingX(char *inbuf,char *outbuf,int length,int bufsize)
- {
- int smb_com2 = CVAL(inbuf,smb_vwv0);
- int smb_off2 = SVAL(inbuf,smb_vwv1);
- int fnum = GETFNUM(inbuf,smb_vwv2);
- uint16 locktype = SVAL(inbuf,smb_vwv3);
- #if 0
- uint32 timeout = IVAL(inbuf,smb_vwv4);
- #endif
- uint16 num_locks = SVAL(inbuf,smb_vwv6);
- uint16 num_ulocks = SVAL(inbuf,smb_vwv7);
- uint32 count, offset;
-
- int cnum;
- int i;
- char *data;
- uint32 ecode, dummy2;
- int outsize, eclass, dummy1;
-
- cnum = SVAL(inbuf,smb_tid);
- if (!OPEN_FNUM(fnum))
- return(ERROR(ERRDOS,ERRbadfid));
-
- if (Protocol >= PROTOCOL_LANMAN1)
- {
- if(HAS_CACHED_ERROR(fnum))
- return (CACHED_ERROR(fnum));
- }
-
- data = smb_buf(inbuf);
- /* Data now points at the beginning of the list
- of smb_unlkrng structs */
- for(i = 0; i < (int)num_ulocks; i++) {
- count = IVAL(data,SMB_LKLEN_OFFSET(i));
- offset = IVAL(data,SMB_LKOFF_OFFSET(i));
- if(!do_unlock(fnum,cnum,count,offset,&eclass, &ecode))
- return ERROR(eclass,ecode);
- }
-
- /* Now do any requested locks */
- data += 10*num_ulocks;
- /* Data now points at the beginning of the list
- of smb_lkrng structs */
- for(i = 0; i < (int)num_locks; i++) {
- count = IVAL(data,SMB_LKLEN_OFFSET(i));
- offset = IVAL(data,SMB_LKOFF_OFFSET(i));
- if(!do_lock(fnum,cnum,count,offset, &eclass, &ecode))
- break;
- }
-
- /* If any of the above locks failed, then we must unlock
- all of the previous locks (X/Open spec). */
- if(i != num_locks && num_locks != 0) {
- for(; i >= 0; i--) {
- count = IVAL(data,SMB_LKLEN_OFFSET(i));
- offset = IVAL(data,SMB_LKOFF_OFFSET(i));
- do_unlock(fnum,cnum,count,offset,&dummy1,&dummy2);
- }
- return ERROR(eclass,ecode);
- }
-
- outsize = set_message(outbuf,2,0,True);
-
- CVAL(outbuf,smb_vwv0) = smb_com2;
- SSVAL(outbuf,smb_vwv1,(outsize+chain_size)-4);
-
- DEBUG(3,("%s lockingX fnum=%d cnum=%d type=%d num_locks=%d num_ulocks=%d\n",
- timestring(),fnum,cnum,locktype,num_locks,num_ulocks));
-
- chain_fnum = fnum;
-
- if (smb_com2 != 0xFF)
- outsize += chain_reply(smb_com2,inbuf,inbuf+smb_off2+4,
- outbuf,outbuf+outsize,
- length,bufsize);
-
- chain_fnum = -1;
-
- return(outsize);
- }
-
-
- /****************************************************************************
- reply to a SMBreadbmpx (read block multiplex) request
- ****************************************************************************/
- int reply_readbmpx(char *inbuf,char *outbuf,int length,int bufsize)
- {
- int cnum,numtoread,fnum;
- int nread = -1;
- int total_read;
- char *data;
- int32 startpos;
- int32 timeout;
- int outsize, mincount, maxcount;
- BOOL ok = False, nonblocking = False;
-
- /* this function doesn't seem to work - disable by default */
- if (!lp_readbmpx())
- return(ERROR(ERRSRV,ERRuseSTD));
-
- outsize = set_message(outbuf,8,0,True);
-
- cnum = SVAL(inbuf,smb_tid);
- fnum = GETFNUM(inbuf,smb_vwv0);
- if (!OPEN_FNUM(fnum))
- return(ERROR(ERRDOS,ERRbadfid));
- if (Protocol >= PROTOCOL_LANMAN1)
- {
- if(HAS_CACHED_ERROR(fnum))
- return (CACHED_ERROR(fnum));
- }
-
- startpos = IVAL(inbuf,smb_vwv1);
- maxcount = SVAL(inbuf,smb_vwv3);
- mincount = SVAL(inbuf,smb_vwv4);
- timeout = IVALS(inbuf,smb_vwv5);
- if(timeout == 0)
- nonblocking = True;
-
- numtoread = MIN(bufsize-outsize,maxcount);
-
- if(numtoread < maxcount)
- {
-
- /* We don't have enough space to read all the
- requested bytes into the buffer, so, while
- this is true we must send our own constructed
- SMB messages back, leaving one to be sent
- back as the return from this function.
- We *should* do this asynchronously so
- other SMB requests get a look in, but I
- want to finish LANMAN1.0 support before the end
- of the century, so..... */
-
- int new_bufsize = MIN(lp_maxxmit(),BUFFER_SIZE);
- char *new_outbuf = (char *)malloc(new_bufsize + SAFETY_MARGIN);
- int num_thisread=0;
- int new_maxcount = maxcount - numtoread; /* Max we should read
- in these temp reads */
- int new_outsize, new_numtoread;
- int32 new_startpos = startpos;
-
- if(!new_outbuf)
- {
- DEBUG(0,("Out of memory in reply_readmpx\n"));
- return(ERROR(ERRSRV,ERRnoresource));
- }
-
- /* Set up the smb header for this intermediate packet */
-
- memset(new_outbuf,0,smb_size);
- new_outsize = set_message(new_outbuf,8,0,True);
- CVAL(new_outbuf,smb_com) = CVAL(inbuf,smb_com);
- memcpy(new_outbuf+4,inbuf+4,4);
- CVAL(new_outbuf,smb_rcls) = SUCCESS;
- CVAL(new_outbuf,smb_reh) = 0;
- CVAL(new_outbuf,smb_flg) = 0x80; /* bit 7 set means a reply */
- SSVAL(new_outbuf,smb_err,SUCCESS);
- SSVAL(new_outbuf,smb_tid,SVAL(inbuf,smb_tid));
- SSVAL(new_outbuf,smb_pid,SVAL(inbuf,smb_pid));
- SSVAL(new_outbuf,smb_uid,SVAL(inbuf,smb_uid));
- SSVAL(new_outbuf,smb_mid,SVAL(inbuf,smb_mid));
-
- new_numtoread = MIN(new_bufsize-new_outsize,new_maxcount);
-
- /* Repeat until we have one read remaining */
- while( nread < new_maxcount)
- {
- ok = False;
- new_outsize = set_message(new_outbuf,8,0,True);
- data = smb_buf(new_outbuf);
-
- {
- if (OPEN_FNUM(fnum) && (Files[fnum].cnum == cnum))
- {
- if (is_locked(fnum,cnum,new_numtoread,new_startpos))
- {
- free(new_outbuf);
- return(ERROR(ERRDOS,ERRlock));
- }
-
-
- num_thisread = read_file(fnum,
- data,
- new_startpos,
- mincount, new_numtoread,
- timeout,
- True);
- ok = True;
- }
- }
-
- if ((num_thisread < 0) || !ok)
- {
- free(new_outbuf);
- return(UNIXERROR(ERRDOS,ERRnoaccess));
- }
-
- /* Update all the counts */
- nread += num_thisread;
- new_startpos += num_thisread;
-
- /* Now set up the buffer and send the message */
- new_outsize += num_thisread;
- SIVAL(new_outbuf,smb_vwv0, new_startpos - num_thisread);
- SSVAL(new_outbuf,smb_vwv2, maxcount);
- SSVAL(new_outbuf,smb_vwv3, -1); /* Don't support smb_remaining yet */
- SSVAL(new_outbuf,smb_vwv6, num_thisread);
- SSVAL(new_outbuf,smb_vwv7, smb_vwv9 - 4); /* Offset of data */
- SSVAL(new_outbuf,smb_vwv8, num_thisread); /* smb_bcc */
- smb_setlen(new_outbuf,new_outsize - 4);
- send_smb(new_outbuf);
-
- DEBUG(3,("%s intermediate readmpx fnum=%d cnum=%d num=%d start=%d nread=%d\n",
- timestring(),fnum,cnum,new_numtoread,new_startpos - num_thisread,
- num_thisread));
-
- }
-
- free(new_outbuf);
- }
-
- /* Here we know we have read nread bytes, so we have
- maxcount - nread bytes left to read. We know this
- will fit in outbuf because of the calculation we
- did earlier.*/
-
- numtoread = maxcount - nread;
- startpos += nread;
- total_read = nread;
- nread = -1;
- ok = False;
-
- data = smb_buf(outbuf);
-
- {
- if (OPEN_FNUM(fnum) && (Files[fnum].cnum == cnum))
- {
- if (is_locked(fnum,cnum,numtoread,startpos))
- return(ERROR(ERRDOS,ERRlock));
-
- nread = read_file(fnum,
- data,
- startpos,
- mincount, numtoread,
- timeout,
- True);
- ok = True;
- }
- }
-
-
- if ((nread < 0) || !ok)
- return(UNIXERROR(ERRDOS,ERRnoaccess));
-
- /* Update totals */
- outsize += nread;
- total_read += nread;
-
- /* Setup the final packet */
- SIVAL(outbuf,smb_vwv0, startpos);
- SSVAL(outbuf,smb_vwv2, total_read);
- SSVAL(outbuf,smb_vwv3, -1); /* Don't support smb_remaining yet */
- SSVAL(outbuf,smb_vwv6, nread);
- SSVAL(outbuf,smb_vwv7, smb_vwv9 - 4); /* Offset of data */
- SSVAL(outbuf,smb_vwv8, nread); /* smb_bcc */
-
- DEBUG(3,("%s readmpx fnum=%d cnum=%d num=%d nread=%d\n",timestring(),fnum,cnum,numtoread,nread));
-
- return(outsize);
- }
-
-
- /****************************************************************************
- reply to a SMBwritebmpx (write block multiplex primary) request
- ****************************************************************************/
- int reply_writebmpx(char *inbuf,char *outbuf)
- {
- int cnum,numtowrite,fnum;
- int nwritten = -1;
- int outsize = 0;
- int32 startpos, timeout;
- int tcount, write_through, smb_doff;
- int fd;
- char *data;
- BOOL ok = False;
-
- cnum = SVAL(inbuf,smb_tid);
- fnum = GETFNUM(inbuf,smb_vwv0);
-
- if (!OPEN_FNUM(fnum))
- return(ERROR(ERRDOS,ERRbadfid));
-
- if (Files[fnum].read_only)
- return(ERROR(ERRSRV,ERRaccess));
-
- if (Protocol >= PROTOCOL_LANMAN1)
- {
- if(HAS_CACHED_ERROR(fnum))
- return (CACHED_ERROR(fnum));
- }
-
- tcount = SVAL(inbuf,smb_vwv1);
- startpos = IVAL(inbuf,smb_vwv3);
- timeout = IVALS(inbuf,smb_vwv5);
- write_through = ((SVAL(inbuf,smb_vwv7) & 1) != 0);
- numtowrite = SVAL(inbuf,smb_vwv10);
- smb_doff = SVAL(inbuf,smb_vwv11);
-
- data = inbuf + 4 + smb_doff;
-
- /* If this fails we need to send an SMBwriteC response,
- not an SMBwritebmpx - set this up now so we don't forget */
- CVAL(outbuf,smb_com) = SMBwritec;
-
- fd = Files[fnum].fd;
-
- if (OPEN_FNUM(fnum) && (Files[fnum].cnum == cnum))
- {
- if (is_locked(fnum,cnum,numtowrite,startpos))
- return(ERROR(ERRDOS,ERRlock));
-
- seek_file(fnum,startpos);
- nwritten = write(fd,data,numtowrite);
- #ifndef NO_FSYNC
- if(write_through)
- fsync(Files[fnum].fd);
- #endif
-
- ok = True;
- }
-
- if(((nwritten == 0) && (numtowrite != 0))||(nwritten < 0) || !ok)
- return(UNIXERROR(ERRDOS,ERRnoaccess));
-
- /* If the maximum to be written to this file
- is greater than what we just wrote then set
- up a secondary struct to be attached to this
- fd, we will use this to cache error messages etc. */
- if(tcount > nwritten)
- {
- write_bmpx_struct *wbms;
- if(Files[fnum].wbmpx_ptr != NULL)
- wbms = Files[fnum].wbmpx_ptr; /* Use an existing struct */
- else
- wbms = (write_bmpx_struct *)malloc(sizeof(write_bmpx_struct));
- if(!wbms)
- {
- DEBUG(0,("Out of memory in reply_readmpx\n"));
- return(ERROR(ERRSRV,ERRnoresource));
- }
- wbms->wr_mode = write_through;
- wbms->wr_discard = False; /* No errors yet */
- wbms->wr_timeout = timeout;
- wbms->wr_total_written = nwritten;
- wbms->wr_errclass = 0;
- wbms->wr_error = 0;
- Files[fnum].wbmpx_ptr = wbms;
- }
-
- /* We are returning successfully, set the message type back to
- SMBwritebmpx */
- CVAL(outbuf,smb_com) = SMBwriteBmpx;
-
- outsize = set_message(outbuf,1,0,True);
-
- SSVAL(outbuf,smb_vwv0,-1); /* We don't support smb_remaining */
-
- DEBUG(3,("%s writebmpx fnum=%d cnum=%d num=%d wrote=%d\n",
- timestring(),fnum,cnum,numtowrite,nwritten));
-
- return(outsize);
- }
-
-
- /****************************************************************************
- reply to a SMBsetattrE
- ****************************************************************************/
- int reply_setattrE(char *inbuf,char *outbuf)
- {
- int cnum,fnum;
- struct utimbuf unix_times;
- int outsize = 0;
-
- outsize = set_message(outbuf,0,0,True);
-
- cnum = SVAL(inbuf,smb_tid);
- fnum = GETFNUM(inbuf,smb_vwv0);
- if (!OPEN_FNUM(fnum))
- return(ERROR(ERRDOS,ERRbadfid));
-
- if(HAS_CACHED_ERROR(fnum))
- return (CACHED_ERROR(fnum));
-
- {
- if(!(OPEN_FNUM(fnum)) || (Files[fnum].cnum != cnum))
- {
- return(ERROR(ERRDOS,ERRbadfid));
- }
-
- /* Convert the DOS times into dos times. Ignore create
- time as UNIX can't set this.
- */
-
- unix_times.actime = make_unix_date2(inbuf+smb_vwv3);
- unix_times.modtime = make_unix_date2(inbuf+smb_vwv5);
- unix_times.actime += LOCAL_TO_GMT*TimeDiff();
- unix_times.modtime += LOCAL_TO_GMT*TimeDiff();
-
- /* Set the date on this file */
- if(utime(Files[fnum].name, &unix_times))
- return(ERROR(ERRDOS,ERRnoaccess));
-
- }
-
- DEBUG(3,("%s reply_setattrE fnum=%d cnum=%d\n",timestring(),fnum,cnum));
-
- return(outsize);
- }
-
-
- /****************************************************************************
- reply to a SMBgetattrE
- ****************************************************************************/
- int reply_getattrE(char *inbuf,char *outbuf)
- {
- int cnum,fnum;
- struct stat sbuf;
- int outsize = 0;
-
- outsize = set_message(outbuf,11,0,True);
-
- cnum = SVAL(inbuf,smb_tid);
- fnum = GETFNUM(inbuf,smb_vwv0);
- if (!OPEN_FNUM(fnum))
- return(ERROR(ERRDOS,ERRbadfid));
-
- if(HAS_CACHED_ERROR(fnum))
- return (CACHED_ERROR(fnum));
-
- {
- int mode;
-
- if(!(OPEN_FNUM(fnum)) || (Files[fnum].cnum != cnum))
- return(ERROR(ERRDOS,ERRbadfid));
-
- /* Do an fstat on this file */
- if(fstat( Files[fnum].fd, &sbuf))
- return(UNIXERROR(ERRDOS,ERRnoaccess));
-
- mode = dos_mode(cnum,Files[fnum].name,&sbuf);
-
- /* Convert the times into dos times. Set create
- date to be last modify date as UNIX doesn't save
- this */
- put_dos_date2(outbuf,smb_vwv0,sbuf.st_mtime);
- put_dos_date2(outbuf,smb_vwv2,sbuf.st_atime);
- put_dos_date2(outbuf,smb_vwv4,sbuf.st_mtime);
- if (mode & aDIR)
- {
- SIVAL(outbuf,smb_vwv6,0);
- SIVAL(outbuf,smb_vwv8,0);
- }
- else
- {
- SIVAL(outbuf,smb_vwv6,sbuf.st_size);
- SIVAL(outbuf,smb_vwv8,sbuf.st_size);
- }
- SSVAL(outbuf,smb_vwv10, mode);
-
- }
-
- DEBUG(3,("%s reply_getattrE fnum=%d cnum=%d\n",timestring(),fnum,cnum));
-
- return(outsize);
- }
-
-
- /****************************************************************************
- reply to a SMBwritebs (write block multiplex secondary) request
- ****************************************************************************/
- int reply_writebs(char *inbuf,char *outbuf)
- {
- int cnum,numtowrite,fnum;
- int nwritten = -1;
- int outsize = 0;
- int32 startpos;
- int tcount, write_through, smb_doff;
- int fd;
- char *data;
- write_bmpx_struct *wbms;
- BOOL ok = False;
-
- cnum = SVAL(inbuf,smb_tid);
- fnum = GETFNUM(inbuf,smb_vwv0);
- if (!OPEN_FNUM(fnum))
- return(ERROR(ERRDOS,ERRbadfid));
-
- if (Files[fnum].read_only)
- return(ERROR(ERRSRV,ERRaccess));
-
- tcount = SVAL(inbuf,smb_vwv1);
- startpos = IVAL(inbuf,smb_vwv2);
- numtowrite = SVAL(inbuf,smb_vwv6);
- smb_doff = SVAL(inbuf,smb_vwv7);
-
- data = inbuf + 4 + smb_doff;
-
- /* We need to send an SMBwriteC response, not an SMBwritebs */
- CVAL(outbuf,smb_com) = SMBwritec;
-
- /* This fd should have an auxiliary struct attached,
- check that it does */
- wbms = Files[fnum].wbmpx_ptr;
- if(!wbms) /* smbd is confused - it can't do this ! */
- return(ERROR(ERRDOS,ERRnoaccess));
-
- /* If write through is set we can return errors, else we must
- cache them */
- write_through = wbms->wr_mode;
-
- /* Check for an earlier error */
- if(wbms->wr_discard)
- return -1; /* Just discard the packet */
-
- if (Files[fnum].read_only)
- {
- if(write_through)
- return(ERROR(ERRSRV,ERRaccess));
- /* Cache the error - it must be returned by another
- file request */
- return(CACHE_ERROR(wbms,ERRSRV,ERRaccess));
- }
-
- fd = Files[fnum].fd;
-
- if (OPEN_FNUM(fnum) && (Files[fnum].cnum == cnum))
- {
- if (is_locked(fnum,cnum,numtowrite,startpos))
- {
- if(write_through)
- {
- /* We are returning an error - delete the aux struct */
- if (wbms) free((char *)wbms);
- Files[fnum].wbmpx_ptr = NULL;
- return(ERROR(ERRDOS,ERRlock));
- }
- return CACHE_ERROR(wbms,ERRDOS,ERRlock);
- }
-
- seek_file(fnum,startpos);
- nwritten = write(fd,data,numtowrite);
- #ifndef NO_FSYNC
- if(write_through)
- fsync(Files[fnum].fd);
- #endif
- ok = True;
- }
-
- if(((nwritten == 0) && (numtowrite != 0))||(nwritten < 0) || !ok)
- {
- if(write_through)
- {
- /* We are returning an error - we can delete the aux struct */
- if (wbms) free((char *)wbms);
- Files[fnum].wbmpx_ptr = NULL;
- return(ERROR(ERRDOS,ERRnoaccess));
- }
- return(CACHE_ERROR(wbms,ERRDOS,ERRnoaccess));
- }
-
- /* Increment the total written, if this matches tcount
- we can discard the auxiliary struct (hurrah !) */
- wbms->wr_total_written += nwritten;
- if(wbms->wr_total_written >= tcount)
- {
- free((char *)wbms);
- Files[fnum].wbmpx_ptr = NULL;
- }
-
- outsize = set_message(outbuf,1,0,True);
-
- SSVAL(outbuf,smb_vwv0,nwritten);
-
- DEBUG(3,("%s writebmpx secondary fnum=%d cnum=%d num=%d wrote=%d\n",timestring(),fnum,cnum,numtowrite,nwritten));
-
- if(!write_through)
- return -1; /* Don't bother with a response */
-
- return(outsize);
- }
-