mirror of
https://git.tartarus.org/simon/putty.git
synced 2025-01-24 16:52:24 +00:00
Propagate file permissions in both directions in Unix pscp and psftp.
I think I have to consider this to be a separate but related change to the wishlist item 'pscp-filemodes'; that was written before the Unix port existed, and referred to the ability to configure the permissions used for files copied from Windows to Unix - which is still not done. [originally from svn r9260]
This commit is contained in:
parent
f14953d9e9
commit
5c00b581c8
32
pscp.c
32
pscp.c
@ -830,12 +830,13 @@ int scp_send_filetimes(unsigned long mtime, unsigned long atime)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int scp_send_filename(char *name, uint64 size, int modes)
|
int scp_send_filename(char *name, uint64 size, int permissions)
|
||||||
{
|
{
|
||||||
if (using_sftp) {
|
if (using_sftp) {
|
||||||
char *fullname;
|
char *fullname;
|
||||||
struct sftp_packet *pktin;
|
struct sftp_packet *pktin;
|
||||||
struct sftp_request *req, *rreq;
|
struct sftp_request *req, *rreq;
|
||||||
|
struct fxp_attrs attrs;
|
||||||
|
|
||||||
if (scp_sftp_targetisdir) {
|
if (scp_sftp_targetisdir) {
|
||||||
fullname = dupcat(scp_sftp_remotepath, "/", name, NULL);
|
fullname = dupcat(scp_sftp_remotepath, "/", name, NULL);
|
||||||
@ -843,8 +844,12 @@ int scp_send_filename(char *name, uint64 size, int modes)
|
|||||||
fullname = dupstr(scp_sftp_remotepath);
|
fullname = dupstr(scp_sftp_remotepath);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
attrs.flags = 0;
|
||||||
|
PUT_PERMISSIONS(attrs, permissions);
|
||||||
|
|
||||||
sftp_register(req = fxp_open_send(fullname, SSH_FXF_WRITE |
|
sftp_register(req = fxp_open_send(fullname, SSH_FXF_WRITE |
|
||||||
SSH_FXF_CREAT | SSH_FXF_TRUNC));
|
SSH_FXF_CREAT | SSH_FXF_TRUNC,
|
||||||
|
&attrs));
|
||||||
rreq = sftp_find_request(pktin = sftp_recv());
|
rreq = sftp_find_request(pktin = sftp_recv());
|
||||||
assert(rreq == req);
|
assert(rreq == req);
|
||||||
scp_sftp_filehandle = fxp_open_recv(pktin, rreq);
|
scp_sftp_filehandle = fxp_open_recv(pktin, rreq);
|
||||||
@ -864,7 +869,9 @@ int scp_send_filename(char *name, uint64 size, int modes)
|
|||||||
char buf[40];
|
char buf[40];
|
||||||
char sizestr[40];
|
char sizestr[40];
|
||||||
uint64_decimal(size, sizestr);
|
uint64_decimal(size, sizestr);
|
||||||
sprintf(buf, "C%04o %s ", modes, sizestr);
|
if (permissions < 0)
|
||||||
|
permissions = 0644;
|
||||||
|
sprintf(buf, "C%04o %s ", (int)(permissions & 07777), sizestr);
|
||||||
back->send(backhandle, buf, strlen(buf));
|
back->send(backhandle, buf, strlen(buf));
|
||||||
back->send(backhandle, name, strlen(name));
|
back->send(backhandle, name, strlen(name));
|
||||||
back->send(backhandle, "\n", 1);
|
back->send(backhandle, "\n", 1);
|
||||||
@ -1144,7 +1151,7 @@ struct scp_sink_action {
|
|||||||
int action; /* FILE, DIR, ENDDIR */
|
int action; /* FILE, DIR, ENDDIR */
|
||||||
char *buf; /* will need freeing after use */
|
char *buf; /* will need freeing after use */
|
||||||
char *name; /* filename or dirname (not ENDDIR) */
|
char *name; /* filename or dirname (not ENDDIR) */
|
||||||
int mode; /* access mode (not ENDDIR) */
|
long permissions; /* access permissions (not ENDDIR) */
|
||||||
uint64 size; /* file size (not ENDDIR) */
|
uint64 size; /* file size (not ENDDIR) */
|
||||||
int settime; /* 1 if atime and mtime are filled */
|
int settime; /* 1 if atime and mtime are filled */
|
||||||
unsigned long atime, mtime; /* access times for the file */
|
unsigned long atime, mtime; /* access times for the file */
|
||||||
@ -1370,7 +1377,7 @@ int scp_get_sink_action(struct scp_sink_action *act)
|
|||||||
act->buf = dupstr(stripslashes(fname, 0));
|
act->buf = dupstr(stripslashes(fname, 0));
|
||||||
act->name = act->buf;
|
act->name = act->buf;
|
||||||
act->size = uint64_make(0,0); /* duhh, it's a directory */
|
act->size = uint64_make(0,0); /* duhh, it's a directory */
|
||||||
act->mode = 07777 & attrs.permissions;
|
act->permissions = 07777 & attrs.permissions;
|
||||||
if (scp_sftp_preserve &&
|
if (scp_sftp_preserve &&
|
||||||
(attrs.flags & SSH_FILEXFER_ATTR_ACMODTIME)) {
|
(attrs.flags & SSH_FILEXFER_ATTR_ACMODTIME)) {
|
||||||
act->atime = attrs.atime;
|
act->atime = attrs.atime;
|
||||||
@ -1392,7 +1399,7 @@ int scp_get_sink_action(struct scp_sink_action *act)
|
|||||||
act->size = attrs.size;
|
act->size = attrs.size;
|
||||||
} else
|
} else
|
||||||
act->size = uint64_make(ULONG_MAX,ULONG_MAX); /* no idea */
|
act->size = uint64_make(ULONG_MAX,ULONG_MAX); /* no idea */
|
||||||
act->mode = 07777 & attrs.permissions;
|
act->permissions = 07777 & attrs.permissions;
|
||||||
if (scp_sftp_preserve &&
|
if (scp_sftp_preserve &&
|
||||||
(attrs.flags & SSH_FILEXFER_ATTR_ACMODTIME)) {
|
(attrs.flags & SSH_FILEXFER_ATTR_ACMODTIME)) {
|
||||||
act->atime = attrs.atime;
|
act->atime = attrs.atime;
|
||||||
@ -1474,7 +1481,8 @@ int scp_get_sink_action(struct scp_sink_action *act)
|
|||||||
{
|
{
|
||||||
char sizestr[40];
|
char sizestr[40];
|
||||||
|
|
||||||
if (sscanf(act->buf, "%o %s %n", &act->mode, sizestr, &i) != 2)
|
if (sscanf(act->buf, "%lo %s %n", &act->permissions,
|
||||||
|
sizestr, &i) != 2)
|
||||||
bump("Protocol error: Illegal file descriptor format");
|
bump("Protocol error: Illegal file descriptor format");
|
||||||
act->size = uint64_from_decimal(sizestr);
|
act->size = uint64_from_decimal(sizestr);
|
||||||
act->name = act->buf + i;
|
act->name = act->buf + i;
|
||||||
@ -1489,7 +1497,8 @@ int scp_accept_filexfer(void)
|
|||||||
struct sftp_packet *pktin;
|
struct sftp_packet *pktin;
|
||||||
struct sftp_request *req, *rreq;
|
struct sftp_request *req, *rreq;
|
||||||
|
|
||||||
sftp_register(req = fxp_open_send(scp_sftp_currentname, SSH_FXF_READ));
|
sftp_register(req = fxp_open_send(scp_sftp_currentname, SSH_FXF_READ,
|
||||||
|
NULL));
|
||||||
rreq = sftp_find_request(pktin = sftp_recv());
|
rreq = sftp_find_request(pktin = sftp_recv());
|
||||||
assert(rreq == req);
|
assert(rreq == req);
|
||||||
scp_sftp_filehandle = fxp_open_recv(pktin, rreq);
|
scp_sftp_filehandle = fxp_open_recv(pktin, rreq);
|
||||||
@ -1609,6 +1618,7 @@ static void source(char *src)
|
|||||||
{
|
{
|
||||||
uint64 size;
|
uint64 size;
|
||||||
unsigned long mtime, atime;
|
unsigned long mtime, atime;
|
||||||
|
long permissions;
|
||||||
char *last;
|
char *last;
|
||||||
RFile *f;
|
RFile *f;
|
||||||
int attr;
|
int attr;
|
||||||
@ -1656,7 +1666,7 @@ static void source(char *src)
|
|||||||
if (last == src && strchr(src, ':') != NULL)
|
if (last == src && strchr(src, ':') != NULL)
|
||||||
last = strchr(src, ':') + 1;
|
last = strchr(src, ':') + 1;
|
||||||
|
|
||||||
f = open_existing_file(src, &size, &mtime, &atime);
|
f = open_existing_file(src, &size, &mtime, &atime, &permissions);
|
||||||
if (f == NULL) {
|
if (f == NULL) {
|
||||||
run_err("%s: Cannot open file", src);
|
run_err("%s: Cannot open file", src);
|
||||||
return;
|
return;
|
||||||
@ -1671,7 +1681,7 @@ static void source(char *src)
|
|||||||
uint64_decimal(size, sizestr);
|
uint64_decimal(size, sizestr);
|
||||||
tell_user(stderr, "Sending file %s, size=%s", last, sizestr);
|
tell_user(stderr, "Sending file %s, size=%s", last, sizestr);
|
||||||
}
|
}
|
||||||
if (scp_send_filename(last, size, 0644))
|
if (scp_send_filename(last, size, permissions))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
stat_bytes = uint64_make(0,0);
|
stat_bytes = uint64_make(0,0);
|
||||||
@ -1888,7 +1898,7 @@ static void sink(char *targ, char *src)
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
f = open_new_file(destfname);
|
f = open_new_file(destfname, act.permissions);
|
||||||
if (f == NULL) {
|
if (f == NULL) {
|
||||||
run_err("%s: Cannot create file", destfname);
|
run_err("%s: Cannot create file", destfname);
|
||||||
continue;
|
continue;
|
||||||
|
24
psftp.c
24
psftp.c
@ -212,6 +212,7 @@ int sftp_get_file(char *fname, char *outfname, int recurse, int restart)
|
|||||||
uint64 offset;
|
uint64 offset;
|
||||||
WFile *file;
|
WFile *file;
|
||||||
int ret, shown_err = FALSE;
|
int ret, shown_err = FALSE;
|
||||||
|
struct fxp_attrs attrs;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* In recursive mode, see if we're dealing with a directory.
|
* In recursive mode, see if we're dealing with a directory.
|
||||||
@ -219,7 +220,6 @@ int sftp_get_file(char *fname, char *outfname, int recurse, int restart)
|
|||||||
* subsequent FXP_OPEN will return a usable error message.)
|
* subsequent FXP_OPEN will return a usable error message.)
|
||||||
*/
|
*/
|
||||||
if (recurse) {
|
if (recurse) {
|
||||||
struct fxp_attrs attrs;
|
|
||||||
int result;
|
int result;
|
||||||
|
|
||||||
sftp_register(req = fxp_stat_send(fname));
|
sftp_register(req = fxp_stat_send(fname));
|
||||||
@ -383,7 +383,13 @@ int sftp_get_file(char *fname, char *outfname, int recurse, int restart)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
sftp_register(req = fxp_open_send(fname, SSH_FXF_READ));
|
sftp_register(req = fxp_stat_send(fname));
|
||||||
|
rreq = sftp_find_request(pktin = sftp_recv());
|
||||||
|
assert(rreq == req);
|
||||||
|
if (!fxp_stat_recv(pktin, rreq, &attrs))
|
||||||
|
attrs.flags = 0;
|
||||||
|
|
||||||
|
sftp_register(req = fxp_open_send(fname, SSH_FXF_READ, NULL));
|
||||||
rreq = sftp_find_request(pktin = sftp_recv());
|
rreq = sftp_find_request(pktin = sftp_recv());
|
||||||
assert(rreq == req);
|
assert(rreq == req);
|
||||||
fh = fxp_open_recv(pktin, rreq);
|
fh = fxp_open_recv(pktin, rreq);
|
||||||
@ -396,7 +402,7 @@ int sftp_get_file(char *fname, char *outfname, int recurse, int restart)
|
|||||||
if (restart) {
|
if (restart) {
|
||||||
file = open_existing_wfile(outfname, NULL);
|
file = open_existing_wfile(outfname, NULL);
|
||||||
} else {
|
} else {
|
||||||
file = open_new_file(outfname);
|
file = open_new_file(outfname, GET_PERMISSIONS(attrs));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!file) {
|
if (!file) {
|
||||||
@ -500,6 +506,8 @@ int sftp_put_file(char *fname, char *outfname, int recurse, int restart)
|
|||||||
uint64 offset;
|
uint64 offset;
|
||||||
RFile *file;
|
RFile *file;
|
||||||
int ret, err, eof;
|
int ret, err, eof;
|
||||||
|
struct fxp_attrs attrs;
|
||||||
|
long permissions;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* In recursive mode, see if we're dealing with a directory.
|
* In recursive mode, see if we're dealing with a directory.
|
||||||
@ -507,7 +515,6 @@ int sftp_put_file(char *fname, char *outfname, int recurse, int restart)
|
|||||||
* subsequent fopen will return an error message.)
|
* subsequent fopen will return an error message.)
|
||||||
*/
|
*/
|
||||||
if (recurse && file_type(fname) == FILE_TYPE_DIRECTORY) {
|
if (recurse && file_type(fname) == FILE_TYPE_DIRECTORY) {
|
||||||
struct fxp_attrs attrs;
|
|
||||||
int result;
|
int result;
|
||||||
int nnames, namesize;
|
int nnames, namesize;
|
||||||
char *name, **ournames;
|
char *name, **ournames;
|
||||||
@ -630,16 +637,19 @@ int sftp_put_file(char *fname, char *outfname, int recurse, int restart)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
file = open_existing_file(fname, NULL, NULL, NULL);
|
file = open_existing_file(fname, NULL, NULL, NULL, &permissions);
|
||||||
if (!file) {
|
if (!file) {
|
||||||
printf("local: unable to open %s\n", fname);
|
printf("local: unable to open %s\n", fname);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
attrs.flags = 0;
|
||||||
|
PUT_PERMISSIONS(attrs, permissions);
|
||||||
if (restart) {
|
if (restart) {
|
||||||
sftp_register(req = fxp_open_send(outfname, SSH_FXF_WRITE));
|
sftp_register(req = fxp_open_send(outfname, SSH_FXF_WRITE, &attrs));
|
||||||
} else {
|
} else {
|
||||||
sftp_register(req = fxp_open_send(outfname, SSH_FXF_WRITE |
|
sftp_register(req = fxp_open_send(outfname, SSH_FXF_WRITE |
|
||||||
SSH_FXF_CREAT | SSH_FXF_TRUNC));
|
SSH_FXF_CREAT | SSH_FXF_TRUNC,
|
||||||
|
&attrs));
|
||||||
}
|
}
|
||||||
rreq = sftp_find_request(pktin = sftp_recv());
|
rreq = sftp_find_request(pktin = sftp_recv());
|
||||||
assert(rreq == req);
|
assert(rreq == req);
|
||||||
|
8
psftp.h
8
psftp.h
@ -85,15 +85,17 @@ void gui_enable(char *arg);
|
|||||||
*/
|
*/
|
||||||
typedef struct RFile RFile;
|
typedef struct RFile RFile;
|
||||||
typedef struct WFile WFile;
|
typedef struct WFile WFile;
|
||||||
/* Output params size, mtime and atime can all be NULL if desired */
|
/* Output params size, perms, mtime and atime can all be NULL if
|
||||||
|
* desired. perms will be -1 if the OS does not support POSIX permissions. */
|
||||||
RFile *open_existing_file(char *name, uint64 *size,
|
RFile *open_existing_file(char *name, uint64 *size,
|
||||||
unsigned long *mtime, unsigned long *atime);
|
unsigned long *mtime, unsigned long *atime,
|
||||||
|
long *perms);
|
||||||
WFile *open_existing_wfile(char *name, uint64 *size);
|
WFile *open_existing_wfile(char *name, uint64 *size);
|
||||||
/* Returns <0 on error, 0 on eof, or number of bytes read, as usual */
|
/* Returns <0 on error, 0 on eof, or number of bytes read, as usual */
|
||||||
int read_from_file(RFile *f, void *buffer, int length);
|
int read_from_file(RFile *f, void *buffer, int length);
|
||||||
/* Closes and frees the RFile */
|
/* Closes and frees the RFile */
|
||||||
void close_rfile(RFile *f);
|
void close_rfile(RFile *f);
|
||||||
WFile *open_new_file(char *name);
|
WFile *open_new_file(char *name, long perms);
|
||||||
/* Returns <0 on error, 0 on eof, or number of bytes written, as usual */
|
/* Returns <0 on error, 0 on eof, or number of bytes written, as usual */
|
||||||
int write_to_file(WFile *f, void *buffer, int length);
|
int write_to_file(WFile *f, void *buffer, int length);
|
||||||
void set_file_times(WFile *f, unsigned long mtime, unsigned long atime);
|
void set_file_times(WFile *f, unsigned long mtime, unsigned long atime);
|
||||||
|
8
sftp.c
8
sftp.c
@ -548,7 +548,8 @@ char *fxp_realpath_recv(struct sftp_packet *pktin, struct sftp_request *req)
|
|||||||
/*
|
/*
|
||||||
* Open a file.
|
* Open a file.
|
||||||
*/
|
*/
|
||||||
struct sftp_request *fxp_open_send(char *path, int type)
|
struct sftp_request *fxp_open_send(char *path, int type,
|
||||||
|
struct fxp_attrs *attrs)
|
||||||
{
|
{
|
||||||
struct sftp_request *req = sftp_alloc_request();
|
struct sftp_request *req = sftp_alloc_request();
|
||||||
struct sftp_packet *pktout;
|
struct sftp_packet *pktout;
|
||||||
@ -557,7 +558,10 @@ struct sftp_request *fxp_open_send(char *path, int type)
|
|||||||
sftp_pkt_adduint32(pktout, req->id);
|
sftp_pkt_adduint32(pktout, req->id);
|
||||||
sftp_pkt_addstring(pktout, path);
|
sftp_pkt_addstring(pktout, path);
|
||||||
sftp_pkt_adduint32(pktout, type);
|
sftp_pkt_adduint32(pktout, type);
|
||||||
sftp_pkt_adduint32(pktout, 0); /* (FIXME) empty ATTRS structure */
|
if (attrs)
|
||||||
|
sftp_pkt_addattrs(pktout, *attrs);
|
||||||
|
else
|
||||||
|
sftp_pkt_adduint32(pktout, 0); /* empty ATTRS structure */
|
||||||
sftp_send(pktout);
|
sftp_send(pktout);
|
||||||
|
|
||||||
return req;
|
return req;
|
||||||
|
19
sftp.h
19
sftp.h
@ -82,6 +82,19 @@ struct fxp_attrs {
|
|||||||
unsigned long mtime;
|
unsigned long mtime;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copy between the possibly-unused permissions field in an fxp_attrs
|
||||||
|
* and a possibly-negative integer containing the same permissions.
|
||||||
|
*/
|
||||||
|
#define PUT_PERMISSIONS(attrs, perms) \
|
||||||
|
((perms) >= 0 ? \
|
||||||
|
((attrs).flags |= SSH_FILEXFER_ATTR_PERMISSIONS, \
|
||||||
|
(attrs).permissions = (perms)) : \
|
||||||
|
((attrs).flags &= ~SSH_FILEXFER_ATTR_PERMISSIONS))
|
||||||
|
#define GET_PERMISSIONS(attrs) \
|
||||||
|
((attrs).flags & SSH_FILEXFER_ATTR_PERMISSIONS ? \
|
||||||
|
(attrs).permissions : -1)
|
||||||
|
|
||||||
struct fxp_handle {
|
struct fxp_handle {
|
||||||
char *hstring;
|
char *hstring;
|
||||||
int hlen;
|
int hlen;
|
||||||
@ -116,9 +129,11 @@ struct sftp_request *fxp_realpath_send(char *path);
|
|||||||
char *fxp_realpath_recv(struct sftp_packet *pktin, struct sftp_request *req);
|
char *fxp_realpath_recv(struct sftp_packet *pktin, struct sftp_request *req);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Open a file.
|
* Open a file. 'attrs' contains attributes to be applied to the file
|
||||||
|
* if it's being created.
|
||||||
*/
|
*/
|
||||||
struct sftp_request *fxp_open_send(char *path, int type);
|
struct sftp_request *fxp_open_send(char *path, int type,
|
||||||
|
struct fxp_attrs *attrs);
|
||||||
struct fxp_handle *fxp_open_recv(struct sftp_packet *pktin,
|
struct fxp_handle *fxp_open_recv(struct sftp_packet *pktin,
|
||||||
struct sftp_request *req);
|
struct sftp_request *req);
|
||||||
|
|
||||||
|
@ -125,7 +125,8 @@ struct RFile {
|
|||||||
};
|
};
|
||||||
|
|
||||||
RFile *open_existing_file(char *name, uint64 *size,
|
RFile *open_existing_file(char *name, uint64 *size,
|
||||||
unsigned long *mtime, unsigned long *atime)
|
unsigned long *mtime, unsigned long *atime,
|
||||||
|
long *perms)
|
||||||
{
|
{
|
||||||
int fd;
|
int fd;
|
||||||
RFile *ret;
|
RFile *ret;
|
||||||
@ -137,7 +138,7 @@ RFile *open_existing_file(char *name, uint64 *size,
|
|||||||
ret = snew(RFile);
|
ret = snew(RFile);
|
||||||
ret->fd = fd;
|
ret->fd = fd;
|
||||||
|
|
||||||
if (size || mtime || atime) {
|
if (size || mtime || atime || perms) {
|
||||||
struct stat statbuf;
|
struct stat statbuf;
|
||||||
if (fstat(fd, &statbuf) < 0) {
|
if (fstat(fd, &statbuf) < 0) {
|
||||||
fprintf(stderr, "%s: stat: %s\n", name, strerror(errno));
|
fprintf(stderr, "%s: stat: %s\n", name, strerror(errno));
|
||||||
@ -153,6 +154,9 @@ RFile *open_existing_file(char *name, uint64 *size,
|
|||||||
|
|
||||||
if (atime)
|
if (atime)
|
||||||
*atime = statbuf.st_atime;
|
*atime = statbuf.st_atime;
|
||||||
|
|
||||||
|
if (perms)
|
||||||
|
*perms = statbuf.st_mode;
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
@ -174,12 +178,13 @@ struct WFile {
|
|||||||
char *name;
|
char *name;
|
||||||
};
|
};
|
||||||
|
|
||||||
WFile *open_new_file(char *name)
|
WFile *open_new_file(char *name, long perms)
|
||||||
{
|
{
|
||||||
int fd;
|
int fd;
|
||||||
WFile *ret;
|
WFile *ret;
|
||||||
|
|
||||||
fd = open(name, O_CREAT | O_TRUNC | O_WRONLY, 0666);
|
fd = open(name, O_CREAT | O_TRUNC | O_WRONLY,
|
||||||
|
(mode_t)(perms ? perms : 0666));
|
||||||
if (fd < 0)
|
if (fd < 0)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
|
@ -88,7 +88,8 @@ struct RFile {
|
|||||||
};
|
};
|
||||||
|
|
||||||
RFile *open_existing_file(char *name, uint64 *size,
|
RFile *open_existing_file(char *name, uint64 *size,
|
||||||
unsigned long *mtime, unsigned long *atime)
|
unsigned long *mtime, unsigned long *atime,
|
||||||
|
long *perms)
|
||||||
{
|
{
|
||||||
HANDLE h;
|
HANDLE h;
|
||||||
RFile *ret;
|
RFile *ret;
|
||||||
@ -113,6 +114,9 @@ RFile *open_existing_file(char *name, uint64 *size,
|
|||||||
TIME_WIN_TO_POSIX(wrtime, *mtime);
|
TIME_WIN_TO_POSIX(wrtime, *mtime);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (perms)
|
||||||
|
*perms = -1;
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -137,7 +141,7 @@ struct WFile {
|
|||||||
HANDLE h;
|
HANDLE h;
|
||||||
};
|
};
|
||||||
|
|
||||||
WFile *open_new_file(char *name)
|
WFile *open_new_file(char *name, long perms)
|
||||||
{
|
{
|
||||||
HANDLE h;
|
HANDLE h;
|
||||||
WFile *ret;
|
WFile *ret;
|
||||||
|
Loading…
Reference in New Issue
Block a user