diff options
author | Colin Percival <cperciva@FreeBSD.org> | 2006-01-11 08:08:08 +0000 |
---|---|---|
committer | Colin Percival <cperciva@FreeBSD.org> | 2006-01-11 08:08:08 +0000 |
commit | a0b6de1c4f9a10df8742abfe06ef2965a747b808 (patch) | |
tree | b2d721005718dbb78e8dbdb3b201a531902e502f | |
parent | 6a0d191c9cc845c251b3dd59a31423475f2dd8be (diff) | |
download | src-test2-a0b6de1c4f9a10df8742abfe06ef2965a747b808.tar.gz src-test2-a0b6de1c4f9a10df8742abfe06ef2965a747b808.zip |
Notes
-rw-r--r-- | UPDATING | 10 | ||||
-rw-r--r-- | contrib/cpio/copyin.c | 117 | ||||
-rw-r--r-- | contrib/cpio/copyout.c | 22 | ||||
-rw-r--r-- | contrib/cpio/copypass.c | 31 | ||||
-rw-r--r-- | contrib/cpio/cpio.1 | 8 | ||||
-rw-r--r-- | contrib/cpio/extern.h | 2 | ||||
-rw-r--r-- | contrib/cpio/global.c | 4 | ||||
-rw-r--r-- | contrib/cpio/main.c | 12 | ||||
-rw-r--r-- | contrib/texinfo/util/texindex.c | 65 | ||||
-rw-r--r-- | sys/conf/newvers.sh | 2 | ||||
-rw-r--r-- | usr.bin/ee/ee.c | 34 |
11 files changed, 240 insertions, 67 deletions
@@ -8,6 +8,16 @@ Items affecting the ports and packages system can be found in /usr/ports/UPDATING. Please read that file before running portupgrade. Important recent entries: 20040724 (default X changes). +20060111: p24 FreeBSD-SA-06:01.texindex, FreeBSD-SA-06:02.ee, + FreeBSD-SA-06:03.cpio + Correct insecure temporary file usage in texindex. [06:01] + + Correct insecure temporary file usage in ee. [06:02] + + Correct a race condition when setting file permissions, + sanitize file names by default, and fix a buffer overflow + when handling files larger than 4GB in cpio. [06:03] + 20051011: p23 FreeBSD-SA-05:21.openssl Correct a man-in-the-middle SSL version rollback vulnerability. diff --git a/contrib/cpio/copyin.c b/contrib/cpio/copyin.c index c3cc7997608f..3bae0ee47768 100644 --- a/contrib/cpio/copyin.c +++ b/contrib/cpio/copyin.c @@ -46,6 +46,19 @@ $FreeBSD$ #define lchown chown #endif +# ifndef DIRECTORY_SEPARATOR +# define DIRECTORY_SEPARATOR '/' +# endif + +# ifndef ISSLASH +# define ISSLASH(C) ((C) == DIRECTORY_SEPARATOR) +# endif + +# ifndef FILE_SYSTEM_PREFIX_LEN +# define FILE_SYSTEM_PREFIX_LEN(Filename) 0 +# endif + + static void read_pattern_file (); static void tape_skip_padding (); static void defer_copyin (); @@ -376,6 +389,54 @@ swab_array (ptr, count) /* Current time for verbose table. */ static time_t current_time; +/* Return a safer suffix of FILE_NAME, or "." if it has no safer + suffix. Check for fully specified file names and other atrocities. */ + +static const char * +safer_name_suffix (char const *file_name) +{ + char const *p; + + /* Skip file system prefixes, leading file name components that contain + "..", and leading slashes. */ + + size_t prefix_len = FILE_SYSTEM_PREFIX_LEN (file_name); + + for (p = file_name + prefix_len; *p;) + { + if (p[0] == '.' && p[1] == '.' && (ISSLASH (p[2]) || !p[2])) + prefix_len = p + 2 - file_name; + + do + { + char c = *p++; + if (ISSLASH (c)) + break; + } + while (*p); + } + + for (p = file_name + prefix_len; ISSLASH (*p); p++) + continue; + prefix_len = p - file_name; + + if (prefix_len) + { + char *prefix = alloca (prefix_len + 1); + memcpy (prefix, file_name, prefix_len); + prefix[prefix_len] = '\0'; + + + error (0, 0, "Removing leading `%s' from member names", prefix); + } + + if (!*p) + p = "."; + + return p; +} + + /* Read the collection from standard input and create files in the file system. */ @@ -396,6 +457,7 @@ process_copy_in () int in_file_des; /* Input file descriptor. */ char skip_file; /* Flag for use with patterns. */ int existing_dir; /* True if file is a dir & already exists. */ + mode_t existing_mode; int i; /* Loop index variable. */ char *link_name = NULL; /* Name of hard and symbolic links. */ #ifdef HPUX_CDF @@ -494,18 +556,11 @@ process_copy_in () /* Do we have to ignore absolute paths, and if so, does the filename have an absolute path? */ - if (no_abs_paths_flag && file_hdr.c_name && file_hdr.c_name [0] == '/') + if (!abs_paths_flag && file_hdr.c_name && file_hdr.c_name[0]) { - char *p; + const char *p = safer_name_suffix (file_hdr.c_name); - p = file_hdr.c_name; - while (*p == '/') - ++p; - if (*p == '\0') - { - strcpy (file_hdr.c_name, "."); - } - else + if (p != file_hdr.c_name) { char *non_abs_name; @@ -642,6 +697,7 @@ process_copy_in () we are trying to create, don't complain about it. */ existing_dir = TRUE; + existing_mode = file_stat.st_mode; } else if (!unconditional_flag && file_hdr.c_mtime <= file_stat.st_mtime) @@ -778,8 +834,6 @@ process_copy_in () } copy_files_tape_to_disk (in_file_des, out_file_des, file_hdr.c_filesize); disk_empty_output_buffer (out_file_des); - if (close (out_file_des) < 0) - error (0, errno, "%s", file_hdr.c_name); if (archive_format == arf_crcascii) { @@ -789,13 +843,15 @@ process_copy_in () } /* File is now copied; set attributes. */ if (!no_chown_flag) - if ((chown (file_hdr.c_name, + if ((fchown (out_file_des, set_owner_flag ? set_owner : file_hdr.c_uid, set_group_flag ? set_group : file_hdr.c_gid) < 0) && errno != EPERM) error (0, errno, "%s", file_hdr.c_name); /* chown may have turned off some permissions we wanted. */ - if (chmod (file_hdr.c_name, (int) file_hdr.c_mode) < 0) + if (fchmod (out_file_des, (int) file_hdr.c_mode) < 0) + error (0, errno, "%s", file_hdr.c_name); + if (close (out_file_des) < 0) error (0, errno, "%s", file_hdr.c_name); if (retain_time_flag) { @@ -847,14 +903,23 @@ process_copy_in () cdf_flag = 1; } #endif - res = mkdir (file_hdr.c_name, file_hdr.c_mode); + res = mkdir (file_hdr.c_name, file_hdr.c_mode & ~077); } else - res = 0; + { + if (!no_chown_flag && (existing_mode & 077) != 0 + && chmod (file_hdr.c_name, existing_mode & 07700) < 0) + { + error (0, errno, "%s: chmod", file_hdr.c_name); + return; + } + res = 0; + } + if (res < 0 && create_dir_flag) { create_all_directories (file_hdr.c_name); - res = mkdir (file_hdr.c_name, file_hdr.c_mode); + res = mkdir (file_hdr.c_name, file_hdr.c_mode & ~077); } if (res < 0) { @@ -936,20 +1001,20 @@ process_copy_in () #ifdef CP_IFIFO if ((file_hdr.c_mode & CP_IFMT) == CP_IFIFO) - res = mkfifo (file_hdr.c_name, file_hdr.c_mode); + res = mkfifo (file_hdr.c_name, file_hdr.c_mode & ~077); else #endif - res = mknod (file_hdr.c_name, file_hdr.c_mode, + res = mknod (file_hdr.c_name, file_hdr.c_mode & ~077, makedev (file_hdr.c_rdev_maj, file_hdr.c_rdev_min)); if (res < 0 && create_dir_flag) { create_all_directories (file_hdr.c_name); #ifdef CP_IFIFO if ((file_hdr.c_mode & CP_IFMT) == CP_IFIFO) - res = mkfifo (file_hdr.c_name, file_hdr.c_mode); + res = mkfifo (file_hdr.c_name, file_hdr.c_mode & ~077); else #endif - res = mknod (file_hdr.c_name, file_hdr.c_mode, + res = mknod (file_hdr.c_name, file_hdr.c_mode & ~077, makedev (file_hdr.c_rdev_maj, file_hdr.c_rdev_min)); } @@ -1376,18 +1441,18 @@ create_final_defers () continue; } - if (close (out_file_des) < 0) - error (0, errno, "%s", d->header.c_name); - + /* File is now copied; set attributes. */ if (!no_chown_flag) - if ((chown (d->header.c_name, + if ((fchown (out_file_des, set_owner_flag ? set_owner : d->header.c_uid, set_group_flag ? set_group : d->header.c_gid) < 0) && errno != EPERM) error (0, errno, "%s", d->header.c_name); /* chown may have turned off some permissions we wanted. */ - if (chmod (d->header.c_name, (int) d->header.c_mode) < 0) + if (fchmod (out_file_des, (int) d->header.c_mode) < 0) + error (0, errno, "%s", d->header.c_name); + if (close (out_file_des) < 0) error (0, errno, "%s", d->header.c_name); if (retain_time_flag) { diff --git a/contrib/cpio/copyout.c b/contrib/cpio/copyout.c index 39890b07ef3b..57eec8bff9cd 100644 --- a/contrib/cpio/copyout.c +++ b/contrib/cpio/copyout.c @@ -49,12 +49,13 @@ write_out_header (file_hdr, out_des) { char ascii_header[112]; char *magic_string; + int ret; if (archive_format == arf_crcascii) magic_string = "070702"; else magic_string = "070701"; - sprintf (ascii_header, + ret = snprintf (ascii_header, sizeof(ascii_header), "%6s%08lx%08lx%08lx%08lx%08lx%08lx%08lx%08lx%08lx%08lx%08lx%08lx%08lx", magic_string, file_hdr->c_ino, file_hdr->c_mode, file_hdr->c_uid, @@ -62,6 +63,10 @@ write_out_header (file_hdr, out_des) file_hdr->c_filesize, file_hdr->c_dev_maj, file_hdr->c_dev_min, file_hdr->c_rdev_maj, file_hdr->c_rdev_min, file_hdr->c_namesize, file_hdr->c_chksum); + if (ret >= sizeof(ascii_header)) { + fprintf(stderr, "Internal overflow, aborting\n"); + exit (1); + } tape_buffered_write (ascii_header, out_des, 110L); /* Write file name to output. */ @@ -71,6 +76,7 @@ write_out_header (file_hdr, out_des) else if (archive_format == arf_oldascii || archive_format == arf_hpoldascii) { char ascii_header[78]; + int ret; #ifndef __MSDOS__ dev_t dev; dev_t rdev; @@ -112,7 +118,7 @@ write_out_header (file_hdr, out_des) if ((file_hdr->c_ino >> 16) != 0) error (0, 0, "%s: truncating inode number", file_hdr->c_name); - sprintf (ascii_header, + ret = snprintf (ascii_header, sizeof(ascii_header), "%06o%06o%06lo%06lo%06lo%06lo%06lo%06o%011lo%06lo%011lo", file_hdr->c_magic & 0xFFFF, dev & 0xFFFF, file_hdr->c_ino & 0xFFFF, file_hdr->c_mode & 0xFFFF, @@ -120,6 +126,10 @@ write_out_header (file_hdr, out_des) file_hdr->c_nlink & 0xFFFF, rdev & 0xFFFF, file_hdr->c_mtime, file_hdr->c_namesize & 0xFFFF, file_hdr->c_filesize); + if (ret >= sizeof(ascii_header)) { + fprintf(stderr, "Internal overflow, aborting\n"); + exit (1); + } tape_buffered_write (ascii_header, out_des, 76L); /* Write file name to output. */ @@ -258,6 +268,14 @@ process_copy_out () file_hdr.c_dev_maj = major (file_stat.st_dev); file_hdr.c_dev_min = minor (file_stat.st_dev); file_hdr.c_ino = file_stat.st_ino; + + /* Skip files larger than 4GB which will cause problems on + 64bit platforms (and just not work on 32bit). */ + if (file_stat.st_size > 0xffffffff) { + error (0, 0, "%s: skipping >4GB file", input_name.ds_string); + continue; + } + /* For POSIX systems that don't define the S_IF macros, we can't assume that S_ISfoo means the standard Unix S_IFfoo bit(s) are set. So do it manually, with a diff --git a/contrib/cpio/copypass.c b/contrib/cpio/copypass.c index 993d720456df..19075e1ac91e 100644 --- a/contrib/cpio/copypass.c +++ b/contrib/cpio/copypass.c @@ -174,18 +174,18 @@ process_copy_pass () disk_empty_output_buffer (out_file_des); if (close (in_file_des) < 0) error (0, errno, "%s", input_name.ds_string); - if (close (out_file_des) < 0) - error (0, errno, "%s", output_name.ds_string); /* Set the attributes of the new file. */ if (!no_chown_flag) - if ((chown (output_name.ds_string, + if ((fchown (out_file_des, set_owner_flag ? set_owner : in_file_stat.st_uid, set_group_flag ? set_group : in_file_stat.st_gid) < 0) && errno != EPERM) error (0, errno, "%s", output_name.ds_string); /* chown may have turned off some permissions we wanted. */ - if (chmod (output_name.ds_string, in_file_stat.st_mode) < 0) + if (fchmod (out_file_des, in_file_stat.st_mode) < 0) + error (0, errno, "%s", output_name.ds_string); + if (close (out_file_des) < 0) error (0, errno, "%s", output_name.ds_string); if (reset_time_flag) { @@ -224,15 +224,24 @@ process_copy_pass () cdf_flag = 1; } #endif - res = mkdir (output_name.ds_string, in_file_stat.st_mode); + res = mkdir (output_name.ds_string, in_file_stat.st_mode & ~077); } else - res = 0; + { + if (!no_chown_flag && (out_file_stat.st_mode & 077) != 0 + && chmod (output_name.ds_string, out_file_stat.st_mode & 07700) < 0) + { + error (0, errno, "%s: chmod", output_name.ds_string); + continue; + } + res = 0; + } + if (res < 0 && create_dir_flag) { create_all_directories (output_name.ds_string); - res = mkdir (output_name.ds_string, in_file_stat.st_mode); + res = mkdir (output_name.ds_string, in_file_stat.st_mode & ~077); } if (res < 0) { @@ -298,20 +307,20 @@ process_copy_pass () { #ifdef S_ISFIFO if (S_ISFIFO (in_file_stat.st_mode)) - res = mkfifo (output_name.ds_string, in_file_stat.st_mode); + res = mkfifo (output_name.ds_string, in_file_stat.st_mode & ~077); else #endif - res = mknod (output_name.ds_string, in_file_stat.st_mode, + res = mknod (output_name.ds_string, in_file_stat.st_mode & ~077, in_file_stat.st_rdev); if (res < 0 && create_dir_flag) { create_all_directories (output_name.ds_string); #ifdef S_ISFIFO if (S_ISFIFO (in_file_stat.st_mode)) - res = mkfifo (output_name.ds_string, in_file_stat.st_mode); + res = mkfifo (output_name.ds_string, in_file_stat.st_mode & ~077); else #endif - res = mknod (output_name.ds_string, in_file_stat.st_mode, + res = mknod (output_name.ds_string, in_file_stat.st_mode & ~077, in_file_stat.st_rdev); } if (res < 0) diff --git a/contrib/cpio/cpio.1 b/contrib/cpio/cpio.1 index b1ba4724c765..b0067c4138d2 100644 --- a/contrib/cpio/cpio.1 +++ b/contrib/cpio/cpio.1 @@ -19,7 +19,7 @@ cpio \- copy files to and from archives [\-\-unconditional] [\-\-verbose] [\-\-block-size=blocks] [\-\-swap-halfwords] [\-\-io-size=bytes] [\-\-pattern-file=file] [\-\-format=format] [\-\-owner=[user][:.][group]] [\-\-no-preserve-owner] [\-\-message=message] -[\-\-force\-local] [\-\-no\-absolute\-filenames] [\-\-sparse] [\-\-only\-verify\-crc] +[\-\-force\-local] [\-\-absolute\-filenames] [\-\-sparse] [\-\-only\-verify\-crc] [\-\-quiet] [\-\-help] [\-\-version] [pattern...] [< archive] .B cpio @@ -251,9 +251,9 @@ current volume number (starting at 1). In the verbose table of contents listing, show numeric UID and GID instead of translating them into names. .TP -.I " \-\-no-absolute-filenames" -In copy-in mode, create all files relative to the current directory, -even if they have an absolute file name in the archive. +.I " \-\-absolute-filenames" +Do not strip leading file name components that contain ".." +and leading slashes from file names in copy-in mode .TP .I " \-\-no-preserve-owner" In copy-in mode and copy-pass mode, do not change the ownership of the diff --git a/contrib/cpio/extern.h b/contrib/cpio/extern.h index 0e1344f64e27..2b5d84162d56 100644 --- a/contrib/cpio/extern.h +++ b/contrib/cpio/extern.h @@ -46,7 +46,7 @@ extern int no_chown_flag; extern int sparse_flag; extern int quiet_flag; extern int only_verify_crc_flag; -extern int no_abs_paths_flag; +extern int abs_paths_flag; extern int last_header_start; extern int copy_matching_files; diff --git a/contrib/cpio/global.c b/contrib/cpio/global.c index 7fb66b2fa698..e633d0e8099c 100644 --- a/contrib/cpio/global.c +++ b/contrib/cpio/global.c @@ -98,8 +98,8 @@ int quiet_flag = FALSE; actually extract the files. */ int only_verify_crc_flag = FALSE; -/* If TRUE, don't use any absolute paths, prefix them by `./'. */ -int no_abs_paths_flag = FALSE; +/* If TRUE, allow any absolute paths */ +int abs_paths_flag = FALSE; #ifdef DEBUG_CPIO /* If TRUE, print debugging information. */ diff --git a/contrib/cpio/main.c b/contrib/cpio/main.c index 20829ef50e1a..1da035a5df7b 100644 --- a/contrib/cpio/main.c +++ b/contrib/cpio/main.c @@ -56,7 +56,7 @@ struct option long_opts[] = {"list", 0, &table_flag, TRUE}, {"make-directories", 0, &create_dir_flag, TRUE}, {"message", 1, 0, 'M'}, - {"no-absolute-filenames", 0, 0, 136}, + {"absolute-filenames", 0, 0, 136}, {"no-preserve-owner", 0, 0, 134}, {"nonmatching", 0, ©_matching_files, FALSE}, {"numeric-uid-gid", 0, &numeric_uid, TRUE}, @@ -105,7 +105,7 @@ Usage: %s {-o|--create} [-0acvABLV] [-C bytes] [-H format] [-M message]\n\ [--unconditional] [--verbose] [--block-size=blocks] [--swap-halfwords]\n\ [--io-size=bytes] [--pattern-file=file] [--format=format]\n\ [--owner=[user][:.][group]] [--no-preserve-owner] [--message=message]\n\ - [--force-local] [--no-absolute-filenames] [--sparse] [--only-verify-crc]\n\ + [--force-local] [--absolute-filenames] [--sparse] [--only-verify-crc]\n\ [--quiet] [--help] [--version] [pattern...] [< archive]\n", program_name); fprintf (fp, "\ @@ -266,8 +266,8 @@ crc newc odc bin ustar tar (all-caps also recognized)", optarg); numeric_uid = TRUE; break; - case 136: /* --no-absolute-filenames */ - no_abs_paths_flag = TRUE; + case 136: /* --absolute-filenames */ + abs_paths_flag = TRUE; break; case 134: /* --no-preserve-owner */ @@ -414,7 +414,7 @@ crc newc odc bin ustar tar (all-caps also recognized)", optarg); || retain_time_flag || no_chown_flag || set_owner_flag || set_group_flag || swap_bytes_flag || swap_halfwords_flag || (append_flag && !(archive_name || output_archive_name)) - || rename_batch_file || no_abs_paths_flag + || rename_batch_file || abs_paths_flag || input_archive_name || (archive_name && output_archive_name)) usage (stderr, 2); if (archive_format == arf_unknown) @@ -429,7 +429,7 @@ crc newc odc bin ustar tar (all-caps also recognized)", optarg); if (argc - 1 != optind || archive_format != arf_unknown || swap_bytes_flag || swap_halfwords_flag || table_flag || rename_flag || append_flag - || rename_batch_file || no_abs_paths_flag) + || rename_batch_file || abs_paths_flag) usage (stderr, 2); directory_name = argv[optind]; } diff --git a/contrib/texinfo/util/texindex.c b/contrib/texinfo/util/texindex.c index f63fdb5ecf27..1e296eecdc29 100644 --- a/contrib/texinfo/util/texindex.c +++ b/contrib/texinfo/util/texindex.c @@ -386,6 +386,21 @@ For more information about these matters, see the files named COPYING.\n"), usage (1); } +static char **tv; +static int tv_alloc; +static int tv_used; + +static int +findtempname (char *tempname) +{ + int i; + + for (i = 0; i < tv_used; i++) + if (strcmp (tv[i], tempname) == 0) + return (1); + return (0); +} + /* Return a name for temporary file COUNT. */ static char * @@ -393,11 +408,12 @@ maketempname (count) int count; { static char *tempbase = NULL; + char *tempname; char tempsuffix[10]; + int fd; if (!tempbase) { - int fd; tempbase = concat (tempdir, "txidxXXXXXX"); fd = mkstemp (tempbase); @@ -406,7 +422,52 @@ maketempname (count) } sprintf (tempsuffix, ".%d", count); - return concat (tempbase, tempsuffix); + tempname = concat (tempbase, tempsuffix); + /* + * The open logic becomes a bit convoluted. If open(2) fails due to EEXIST, + * it's likely because somebody attempted to race us, or because we have + * already created this file. + */ + fd = open (tempname, O_CREAT|O_EXCL|O_WRONLY, 0600); + if (fd == -1) + { + /* + * If errno is not EEXIST, then open failed for some other reason, so + * we should terminate. If errno == EEXIST AND we didn't create this + * file, terminate. Otherwise, it's safe to say that errno == EEXIST + * because we already created it, in this event, we can just return. + */ + if (errno != EEXIST || + (errno == EEXIST && findtempname (tempname) == 0)) + pfatal_with_name (tempname); + return (tempname); + } + else if (fd > 0) + { + close (fd); + } + if (tv == NULL) + { + tv_alloc = 16; + tv = calloc (tv_alloc, sizeof (char *)); + if (tv == NULL) + { + fprintf (stderr, "calloc failed\n"); + exit (1); + } + } + else if (tv_used == tv_alloc) + { + tv_alloc += 4; + tv = realloc (tv, tv_alloc * sizeof (char *)); + if (tv == NULL) + { + fprintf (stderr, "realloc failed"); + exit (1); + } + } + tv[tv_used++] = strdup (tempname); + return tempname; } diff --git a/sys/conf/newvers.sh b/sys/conf/newvers.sh index 2c455beaa282..12505b9d3b95 100644 --- a/sys/conf/newvers.sh +++ b/sys/conf/newvers.sh @@ -32,7 +32,7 @@ TYPE="FreeBSD" REVISION="5.3" -BRANCH="RELEASE-p23" +BRANCH="RELEASE-p24" RELEASE="${REVISION}-${BRANCH}" VERSION="${TYPE} ${RELEASE}" diff --git a/usr.bin/ee/ee.c b/usr.bin/ee/ee.c index 65ca72de49e4..15801b0edd45 100644 --- a/usr.bin/ee/ee.c +++ b/usr.bin/ee/ee.c @@ -300,7 +300,7 @@ void finish P_((void)); int quit P_((int noverify)); void edit_abort P_((int arg)); void delete_text P_((void)); -int write_file P_((char *file_name)); +int write_file P_((char *file_name, int warn_if_exists)); int search P_((int display_message)); void search_prompt P_((void)); void del_char P_((void)); @@ -1687,7 +1687,7 @@ char *cmd_str1; cmd_str = cmd_str2 = get_string(file_write_prompt_str, TRUE); } tmp_file = resolve_name(cmd_str); - write_file(tmp_file); + write_file(tmp_file, 1); if (tmp_file != cmd_str) free(tmp_file); } @@ -2394,7 +2394,7 @@ finish() /* prepare to exit edit session */ file_name = tmp_file; } - if (write_file(file_name)) + if (write_file(file_name, 1)) { text_changes = FALSE; quit(0); @@ -2471,8 +2471,9 @@ delete_text() } int -write_file(file_name) +write_file(file_name, warn_if_exists) char *file_name; +int warn_if_exists; { char cr; char *tmp_point; @@ -2482,7 +2483,8 @@ char *file_name; int write_flag = TRUE; charac = lines = 0; - if ((in_file_name == NULL) || strcmp(in_file_name, file_name)) + if (warn_if_exists && + ((in_file_name == NULL) || strcmp(in_file_name, file_name))) { if ((temp_fp = fopen(file_name, "r"))) { @@ -3724,7 +3726,7 @@ int arg; { string = get_string(file_write_prompt_str, TRUE); tmp_file = resolve_name(string); - write_file(tmp_file); + write_file(tmp_file, 1); if (tmp_file != string) free(tmp_file); free(string); @@ -3761,7 +3763,7 @@ int arg; string = tmp_file; } } - if (write_file(string)) + if (write_file(string, 1)) { in_file_name = string; text_changes = FALSE; @@ -4374,17 +4376,25 @@ spell_op() /* check spelling of words in the editor */ void ispell_op() { - char name[128]; + char template[128], *name; char string[256]; - int pid; + int fd; if (restrict_mode()) { return; } - pid = getpid(); - sprintf(name, "/tmp/ee.%d", pid); - if (write_file(name)) + (void)sprintf(template, "/tmp/ee.XXXXXXXX"); + name = mktemp(&template[0]); + fd = open(name, O_CREAT | O_EXCL | O_RDWR, 0600); + if (fd < 0) { + wmove(com_win, 0, 0); + wprintw(com_win, create_file_fail_msg, name); + wrefresh(com_win); + return; + } + close(fd); + if (write_file(name, 0)) { sprintf(string, "ispell %s", name); sh_command(string); |