extern connection_struct Connections[];
extern files_struct Files[];
extern BOOL case_sensitive;
+extern BOOL case_preserve;
extern pstring sesssetup_user;
extern int Client;
cnum = SVAL(inbuf,smb_tid);
strcpy(name,smb_buf(inbuf) + 1);
- unix_convert(name,cnum);
+ unix_convert(name,cnum,0);
mode = SVAL(inbuf,smb_vwv0);
cnum = SVAL(inbuf,smb_tid);
strcpy(fname,smb_buf(inbuf) + 1);
- unix_convert(fname,cnum);
+ unix_convert(fname,cnum,0);
/* dos smetimes asks for a stat of "" - it returns a "hidden directory"
under WfWg - weird! */
cnum = SVAL(inbuf,smb_tid);
strcpy(fname,smb_buf(inbuf) + 1);
- unix_convert(fname,cnum);
+ unix_convert(fname,cnum,0);
mode = SVAL(inbuf,smb_vwv0);
mtime = make_unix_date3(inbuf+smb_vwv1);
strcpy(directory,smb_buf(inbuf)+1);
strcpy(dir2,smb_buf(inbuf)+1);
- unix_convert(directory,cnum);
+ unix_convert(directory,cnum,0);
unix_format(dir2);
if (!check_name(directory,cnum))
share_mode = SVAL(inbuf,smb_vwv0);
strcpy(fname,smb_buf(inbuf)+1);
- unix_convert(fname,cnum);
+ unix_convert(fname,cnum,0);
fnum = find_free_file();
if (fnum < 0)
/* XXXX we need to handle passed times, sattr and flags */
strcpy(fname,smb_buf(inbuf));
- unix_convert(fname,cnum);
+ unix_convert(fname,cnum,0);
/* now add create and trunc bits */
if (smb_ofun & 0x10)
createmode = SVAL(inbuf,smb_vwv0);
strcpy(fname,smb_buf(inbuf)+1);
- unix_convert(fname,cnum);
+ unix_convert(fname,cnum,0);
if (createmode & aVOLID)
{
cnum = SVAL(inbuf,smb_tid);
createmode = SVAL(inbuf,smb_vwv0);
sprintf(fname,"%s/TMXXXXXX",smb_buf(inbuf)+1);
- unix_convert(fname,cnum);
+ unix_convert(fname,cnum,0);
unixmode = unix_mode(cnum,createmode);
DEBUG(3,("reply_unlink : %s\n",name));
- unix_convert(name,cnum);
+ unix_convert(name,cnum,0);
p = strrchr(name,'/');
if (!p) {
strcpy(directory,smb_buf(inbuf) + 1);
cnum = SVAL(inbuf,smb_tid);
- unix_convert(directory,cnum);
+ unix_convert(directory,cnum,0);
if (check_name(directory,cnum))
ret = sys_mkdir(directory,unix_mode(cnum,aDIR));
cnum = SVAL(inbuf,smb_tid);
strcpy(directory,smb_buf(inbuf) + 1);
- unix_convert(directory,cnum);
+ unix_convert(directory,cnum,0);
if (check_name(directory,cnum))
{
int cnum;
pstring directory;
pstring mask,newname;
+ pstring newname_last_component;
char *p;
int count=0;
int error = ERRnoaccess;
DEBUG(3,("reply_mv : %s -> %s\n",name,newname));
- unix_convert(name,cnum);
- unix_convert(newname,cnum);
+ unix_convert(name,cnum,0);
+ unix_convert(newname,cnum,newname_last_component);
p = strrchr(name,'/');
if (!p) {
*p = 0;
strcpy(directory,name);
strcpy(mask,p+1);
+ *p = '/'; /* Replace needed for exceptional test below. */
}
if (is_mangled(mask))
if (!has_wild) {
strcat(directory,"/");
strcat(directory,mask);
+
+ DEBUG(3,("reply_mv : case_sensitive = %d, case_preserve = %d, name = %s, newname = %s, newname_last_component = %s\n", case_sensitive, case_preserve, name, newname, newname_last_component));
+
+ /*
+ * Check for special case with case preserving and not
+ * case sensitive, if name and newname are identical,
+ * and the old last component differs from the original
+ * last component only by case, then we should allow
+ * the rename (user is trying to change the case of the
+ * filename).
+ */
+ if((case_sensitive == False) && (case_preserve == True) &&
+ strcsequal(name, newname)) {
+ pstring newname_modified_last_component;
+
+ /*
+ * Get the last component of the modified name.
+ */
+ p = strrchr(newname,'/');
+ if (!p)
+ strcpy(newname_modified_last_component,name);
+ else
+ strcpy(newname_modified_last_component,p+1);
+
+ if(strcsequal(newname_modified_last_component,
+ newname_last_component) == False) {
+ /*
+ * Replace the modified last component with
+ * the original.
+ */
+ if(p)
+ strcpy(p+1, newname_last_component);
+ else
+ strcpy(newname, newname_last_component);
+ }
+ }
+
if (resolve_wildcards(directory,newname) &&
can_rename(directory,cnum) &&
!file_exist(newname,NULL) &&
!sys_rename(directory,newname)) count++;
+
+ DEBUG(3,("reply_mv : doing rename on %s -> %s\n",directory,newname));
+
if (!count) exists = file_exist(directory,NULL);
if (!count && exists && file_exist(newname,NULL)) {
exists = True;
return(ERROR(ERRSRV,ERRinvdevice));
}
- unix_convert(name,cnum);
- unix_convert(newname,cnum);
+ unix_convert(name,cnum,0);
+ unix_convert(newname,cnum,0);
target_is_directory = directory_exist(newname,NULL);
The function will return False if some part of the name except for the last
part cannot be resolved
+
+If the saved_last_component != 0, then the unmodified last component
+of the pathname is returned there. This is used in an exceptional
+case in reply_mv (so far). If saved_last_component == 0 then nothing
+is returned there.
****************************************************************************/
-BOOL unix_convert(char *name,int cnum)
+BOOL unix_convert(char *name,int cnum,pstring saved_last_component)
{
struct stat st;
char *start, *end;
pstring dirpath;
*dirpath = 0;
+ if(saved_last_component)
+ *saved_last_component = 0;
/* convert to basic unix format - removing \ chars and cleaning it up */
unix_format(name);
return(True);
}
+ /*
+ * Ensure saved_last_component is valid even if file exists.
+ */
+ if(saved_last_component) {
+ end = strrchr(name, '/');
+ if(end)
+ strcpy(saved_last_component, end + 1);
+ else
+ strcpy(saved_last_component, name);
+ }
+
/* stat the name - if it exists then we are all done! */
if (sys_stat(name,&st) == 0)
return(True);
end = strchr(start, '/');
/* chop the name at this point */
- if (end) *end = 0;
+ if (end) *end = 0;
+
+ if(saved_last_component != 0)
+ strcpy(saved_last_component, end ? end + 1 : start);
/* check if the name exists up to this point */
if (sys_stat(name, &st) == 0)
later */
if (end) strcpy(rest,end+1);
-
/* try to find this part of the path in the directory */
if (strchr(start,'?') || strchr(start,'*') ||
!scan_directory(dirpath, start, SNUM(cnum), end?True:False))
/* XXXX we need to handle passed times, sattr and flags */
- unix_convert(fname,cnum);
+ unix_convert(fname,cnum,0);
fnum = find_free_file();
if (fnum < 0)
DEBUG(5,("path=%s\n",directory));
- unix_convert(directory,cnum);
+ unix_convert(directory,cnum,0);
if(!check_name(directory,cnum)) {
return(ERROR(ERRDOS,ERRbadpath));
}
info_level = SVAL(params,0);
fname = &fname1[0];
strcpy(fname,¶ms[6]);
- unix_convert(fname,cnum);
+ unix_convert(fname,cnum,0);
if (!check_name(fname,cnum) || sys_stat(fname,&sbuf)) {
DEBUG(3,("fileinfo of %s failed (%s)\n",fname,strerror(errno)));
return(UNIXERROR(ERRDOS,ERRbadpath));
info_level = SVAL(params,0);
fname = fname1;
strcpy(fname,¶ms[6]);
- unix_convert(fname,cnum);
+ unix_convert(fname,cnum,0);
if(!check_name(fname, cnum))
return(ERROR(ERRDOS,ERRbadpath));
DEBUG(3,("call_trans2mkdir : name = %s\n", directory));
- unix_convert(directory,cnum);
+ unix_convert(directory,cnum,0);
if (check_name(directory,cnum))
ret = sys_mkdir(directory,unix_mode(cnum,aDIR));