Commit 1bd0ce28 authored by Chris Allegretta's avatar Chris Allegretta
Browse files

Okay, now the permissions should be fixed too

git-svn-id: svn://svn.savannah.gnu.org/nano/trunk/nano@390 35c25a1d-7b9e-4130-9fde-d3aeb78583b8
No related merge requests found
Showing with 79 additions and 82 deletions
+79 -82
...@@ -13,6 +13,8 @@ General ...@@ -13,6 +13,8 @@ General
- OOPS, line up link/unlink/rename check if conditional with - OOPS, line up link/unlink/rename check if conditional with
top if conditional. Option -l has been broken for 9 versions, top if conditional. Option -l has been broken for 9 versions,
no one noticed?! no one noticed?!
- Added saving perms at end of link so we can apply them to the
new file if --nofollow is used.
- winio.c: - winio.c:
edit_add() edit_add()
- Off by one display error (fix by Rocco Corsi). - Off by one display error (fix by Rocco Corsi).
......
...@@ -257,9 +257,9 @@ int do_insertfile(void) ...@@ -257,9 +257,9 @@ int do_insertfile(void)
#endif #endif
#ifndef DISABLE_TABCOMP #ifndef DISABLE_TABCOMP
realname = real_dir_from_tilde(answer); realname = real_dir_from_tilde(answer);
#else #else
realname = mallocstrcpy(realname, answer); realname = mallocstrcpy(realname, answer);
#endif #endif
i = open_file(realname, 1, 0); i = open_file(realname, 1, 0);
...@@ -302,7 +302,7 @@ int write_file(char *name, int tmp) ...@@ -302,7 +302,7 @@ int write_file(char *name, int tmp)
char buf[PATH_MAX + 1]; char buf[PATH_MAX + 1];
filestruct *fileptr; filestruct *fileptr;
int fd, mask = 0, realexists, anyexists; int fd, mask = 0, realexists, anyexists;
struct stat st, st2; struct stat st, lst, st2;
static char *realname = NULL; static char *realname = NULL;
if (!strcmp(name, "")) { if (!strcmp(name, "")) {
...@@ -321,31 +321,29 @@ int write_file(char *name, int tmp) ...@@ -321,31 +321,29 @@ int write_file(char *name, int tmp)
realname = mallocstrcpy(realname, name); realname = mallocstrcpy(realname, name);
#endif #endif
/* Save the state of file at the end of the symlink */ /* Save the state of file at the end of the symlink (if there is one) */
realexists = stat(realname, &st); realexists = stat(realname, &st);
/* Check to see if the file is a regular file and FOLLOW_SYMLINKS is /* Stat the link itself for the check... */
set. If so then don't do the delete and recreate code which would anyexists = lstat(realname, &lst);
cause unexpected behavior */
anyexists = lstat(realname, &st);
/* New case: if the file exists, just give up */ /* New case: if the file exists, just give up */
if (tmp && anyexists != -1) if (tmp && anyexists != -1)
return -1; return -1;
/* NOTE: If you change this statement, you MUST CHANGE the if /* NOTE: If you change this statement, you MUST CHANGE the if
statement below (that starts "if ((!ISSET(FOLLOW_SYMLINKS)...") statement below (that starts "if ((!ISSET(FOLLOW_SYMLINKS)...")
to reflect whether or not to link/unlink/rename the file */ to reflect whether or not to link/unlink/rename the file */
else if (ISSET(FOLLOW_SYMLINKS) || !S_ISLNK(st.st_mode)) { else if (ISSET(FOLLOW_SYMLINKS) || !S_ISLNK(lst.st_mode) || tmp) {
/* Use O_EXCL if tmp == 1, I suppose */ /* Use O_EXCL if tmp == 1, I suppose */
if (tmp) if (tmp)
fd = open(realname, O_WRONLY | O_CREAT | O_EXCL | O_TRUNC, fd = open(realname, O_WRONLY | O_CREAT | O_EXCL | O_TRUNC,
S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH |
S_IWOTH); S_IWOTH);
else else
fd = open(realname, O_WRONLY | O_CREAT | O_TRUNC, fd = open(realname, O_WRONLY | O_CREAT | O_TRUNC,
S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH |
S_IWOTH); S_IWOTH);
/* First, just give up if we couldn't even open the file */ /* First, just give up if we couldn't even open the file */
if (fd == -1) { if (fd == -1) {
...@@ -362,11 +360,11 @@ int write_file(char *name, int tmp) ...@@ -362,11 +360,11 @@ int write_file(char *name, int tmp)
/* Now we fstat() the file, to make sure it's the same file still! /* Now we fstat() the file, to make sure it's the same file still!
Thanks to Oliver Friedrichs(?) for this code from securityfocus */ Thanks to Oliver Friedrichs(?) for this code from securityfocus */
if (fstat(fd, &st2) != 0) { if (fstat(fd, &st2) != 0) {
close(fd); close(fd);
return -1; return -1;
} }
} }
/* Don't follow symlink. Create new file. */ /* Don't follow symlink. Create new file. */
else { else {
...@@ -434,55 +432,53 @@ int write_file(char *name, int tmp) ...@@ -434,55 +432,53 @@ int write_file(char *name, int tmp)
return -1; return -1;
} }
if ((!ISSET(FOLLOW_SYMLINKS) && S_ISLNK(st.st_mode)) || tmp) { if (realexists == -1 || tmp ||
if (realexists == -1) { (!ISSET(FOLLOW_SYMLINKS) && S_ISLNK(lst.st_mode))) {
/* Use default umask as file permisions if file is a new file. */
mask = umask(0);
umask(mask);
if (tmp) /* We don't want anyone reading our temporary file! */ /* Use default umask as file permisions if file is a new file. */
mask = 0600; mask = umask(0);
else umask(mask);
mask = 0666 & ~mask;
} else {
/* Use permissions from file we are overwriting. */
mask = st.st_mode;
if (unlink(realname) == -1) {
if (errno != ENOENT) {
statusbar(_("Could not open %s for writing: %s"),
realname, strerror(errno));
unlink(buf);
return -1;
}
}
}
if (!tmp) { if (tmp) /* We don't want anyone reading our temporary file! */
if (link(buf, realname) != -1) mask = 0600;
unlink(buf); else
else if (errno != EPERM) { mask = 0666 & ~mask;
} else
mask = st.st_mode;
if (!tmp && (!ISSET(FOLLOW_SYMLINKS) && S_ISLNK(lst.st_mode))) {
/* Use permissions from file we are overwriting. */
if (unlink(realname) == -1) {
if (errno != ENOENT) {
statusbar(_("Could not open %s for writing: %s"), statusbar(_("Could not open %s for writing: %s"),
name, strerror(errno)); realname, strerror(errno));
unlink(buf);
return -1;
} else if (rename(buf, realname) == -1) { /* Try a rename?? */
statusbar(_("Could not open %s for writing: %s"),
realname, strerror(errno));
unlink(buf); unlink(buf);
return -1; return -1;
} }
} }
if (chmod(realname, mask) == -1) if (link(buf, realname) != -1)
statusbar(_("Could not set permissions %o on %s: %s"), unlink(buf);
mask, realname, strerror(errno)); else if (errno != EPERM) {
statusbar(_("Could not open %s for writing: %s"),
name, strerror(errno));
unlink(buf);
return -1;
} else if (rename(buf, realname) == -1) { /* Try a rename?? */
statusbar(_("Could not open %s for writing: %s"),
realname, strerror(errno));
unlink(buf);
return -1;
}
} }
if (chmod(realname, mask) == -1)
statusbar(_("Could not set permissions %o on %s: %s"),
mask, realname, strerror(errno));
if (!tmp) { if (!tmp) {
strncpy(filename, realname, 132); strncpy(filename, realname, 132);
statusbar(_("Wrote %d lines"), lineswritten); statusbar(_("Wrote %d lines"), lineswritten);
UNSET(MODIFIED); UNSET(MODIFIED);
titlebar(); titlebar();
} }
return 1; return 1;
} }
...@@ -521,10 +517,11 @@ int do_writeout(int exiting) ...@@ -521,10 +517,11 @@ int do_writeout(int exiting)
#endif #endif
#ifdef NANO_EXTRA #ifdef NANO_EXTRA
if (exiting && !ISSET(TEMP_OPT) && !strcasecmp(answer, "zzy") && !did_cred) { if (exiting && !ISSET(TEMP_OPT) && !strcasecmp(answer, "zzy")
&& !did_cred) {
do_credits(); do_credits();
did_cred = 1; did_cred = 1;
return - 1; return -1;
} }
#endif #endif
if (strcmp(answer, filename)) { if (strcmp(answer, filename)) {
...@@ -559,7 +556,7 @@ static char **homedirs; ...@@ -559,7 +556,7 @@ static char **homedirs;
/* Return a malloc()ed string containing the actual directory, used /* Return a malloc()ed string containing the actual directory, used
* to convert ~user and ~/ notation... * to convert ~user and ~/ notation...
*/ */
char *real_dir_from_tilde (char *buf) char *real_dir_from_tilde(char *buf)
{ {
char *dirtmp = NULL, *line = NULL, byte[1], *lineptr; char *dirtmp = NULL, *line = NULL, byte[1], *lineptr;
int fd, i, status, searchctr = 1; int fd, i, status, searchctr = 1;
...@@ -573,30 +570,29 @@ char *real_dir_from_tilde (char *buf) ...@@ -573,30 +570,29 @@ char *real_dir_from_tilde (char *buf)
sprintf(dirtmp, "%s/%s", getenv("HOME"), &buf[2]); sprintf(dirtmp, "%s/%s", getenv("HOME"), &buf[2]);
} }
} } else if (buf[1] != 0) {
else if (buf[1] != 0) {
if((fd = open("/etc/passwd", O_RDONLY)) == -1) if ((fd = open("/etc/passwd", O_RDONLY)) == -1)
goto abort; goto abort;
/* Figure how how much of of the str we need to compare */ /* Figure how how much of of the str we need to compare */
for (searchctr = 1; buf[searchctr] != '/' && for (searchctr = 1; buf[searchctr] != '/' &&
buf[searchctr] != 0; searchctr++) buf[searchctr] != 0; searchctr++);
;
do { do {
i = 0; i = 0;
line = nmalloc(1); line = nmalloc(1);
while ((status = read(fd, byte, 1)) != 0 && byte[0] != '\n') { while ((status = read(fd, byte, 1)) != 0
&& byte[0] != '\n') {
line[i] = byte[0]; line[i] = byte[0];
i++; i++;
line = nrealloc(line, i+1); line = nrealloc(line, i + 1);
} }
line[i] = 0; line[i] = 0;
if (i == 0) if (i == 0)
goto abort; goto abort;
line[i] = 0; line[i] = 0;
lineptr = strtok(line, ":"); lineptr = strtok(line, ":");
...@@ -610,25 +606,24 @@ char *real_dir_from_tilde (char *buf) ...@@ -610,25 +606,24 @@ char *real_dir_from_tilde (char *buf)
if (lineptr == NULL) if (lineptr == NULL)
goto abort; goto abort;
/* Else copy the new string into the new buf */ /* Else copy the new string into the new buf */
dirtmp = nmalloc(strlen(buf) + 2 + strlen(lineptr)); dirtmp = nmalloc(strlen(buf) + 2 + strlen(lineptr));
sprintf(dirtmp, "%s%s", lineptr, &buf[searchctr]); sprintf(dirtmp, "%s%s", lineptr, &buf[searchctr]);
free(line); free(line);
break; break;
} }
free(line); free(line);
} while (status != 0); } while (status != 0);
} }
} } else
else
dirtmp = mallocstrcpy(dirtmp, buf); dirtmp = mallocstrcpy(dirtmp, buf);
return dirtmp; return dirtmp;
abort: abort:
dirtmp = mallocstrcpy(dirtmp, buf); dirtmp = mallocstrcpy(dirtmp, buf);
return dirtmp; return dirtmp;
} }
...@@ -643,7 +638,7 @@ int append_slash_if_dir(char *buf, int *lastWasTab, int *place) ...@@ -643,7 +638,7 @@ int append_slash_if_dir(char *buf, int *lastWasTab, int *place)
dirptr = real_dir_from_tilde(buf); dirptr = real_dir_from_tilde(buf);
if (stat(dirptr, &fileinfo) == -1) if (stat(dirptr, &fileinfo) == -1)
ret = 0; ret = 0;
else if (S_ISDIR(fileinfo.st_mode)) { else if (S_ISDIR(fileinfo.st_mode)) {
strncat(buf, "/", 1); strncat(buf, "/", 1);
*place += 1; *place += 1;
...@@ -653,7 +648,7 @@ int append_slash_if_dir(char *buf, int *lastWasTab, int *place) ...@@ -653,7 +648,7 @@ int append_slash_if_dir(char *buf, int *lastWasTab, int *place)
} }
if (dirptr != buf) if (dirptr != buf)
free(dirptr); free(dirptr);
return ret; return ret;
} }
...@@ -681,11 +676,11 @@ char **username_tab_completion(char *buf, int *num_matches) ...@@ -681,11 +676,11 @@ char **username_tab_completion(char *buf, int *num_matches)
{ {
char **matches = (char **) NULL, *line = NULL, *lineptr; char **matches = (char **) NULL, *line = NULL, *lineptr;
char *matchline = NULL, *matchdir = NULL; char *matchline = NULL, *matchdir = NULL;
int fd, i = 0, status = 1; int fd, i = 0, status = 1;
char byte[1]; char byte[1];
if((fd = open("/etc/passwd", O_RDONLY)) == -1) { if ((fd = open("/etc/passwd", O_RDONLY)) == -1) {
return NULL; return NULL;
} }
...@@ -706,7 +701,7 @@ char **username_tab_completion(char *buf, int *num_matches) ...@@ -706,7 +701,7 @@ char **username_tab_completion(char *buf, int *num_matches)
line[i] = byte[0]; line[i] = byte[0];
i++; i++;
line = nrealloc(line, i+1); line = nrealloc(line, i + 1);
} }
if (i == 0) if (i == 0)
...@@ -885,8 +880,8 @@ char *input_tab(char *buf, int place, int *lastWasTab, int *newplace) ...@@ -885,8 +880,8 @@ char *input_tab(char *buf, int place, int *lastWasTab, int *newplace)
* then try completing this word as a username. */ * then try completing this word as a username. */
/* FIXME -- this check is broken! */ /* FIXME -- this check is broken! */
if (*tmp == '~' && !strchr(tmp, '/')) if (*tmp == '~' && !strchr(tmp, '/'))
matches = username_tab_completion(tmp, &num_matches); matches = username_tab_completion(tmp, &num_matches);
/* Try to match everything in the current working directory that /* Try to match everything in the current working directory that
* matches. */ * matches. */
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment