X-Git-Url: http://ncurses.scripts.mit.edu/?p=ncurses.git;a=blobdiff_plain;f=ncurses%2Ftinfo%2Fwrite_entry.c;h=5bb7aee7f3603ccd1e4cf27e97c44e62e653c9e8;hp=1949f0702110549e99161e1a8305157c79d62f23;hb=HEAD;hpb=4f56e7e405530c9c5e953d4072415429878b6e5b diff --git a/ncurses/tinfo/write_entry.c b/ncurses/tinfo/write_entry.c index 1949f070..8ccca9ec 100644 --- a/ncurses/tinfo/write_entry.c +++ b/ncurses/tinfo/write_entry.c @@ -1,5 +1,6 @@ /**************************************************************************** - * Copyright (c) 1998-2018,2019 Free Software Foundation, Inc. * + * Copyright 2018-2023,2024 Thomas E. Dickey * + * Copyright 1998-2016,2017 Free Software Foundation, Inc. * * * * Permission is hereby granted, free of charge, to any person obtaining a * * copy of this software and associated documentation files (the * @@ -41,6 +42,8 @@ #include +MODULE_ID("$Id: write_entry.c,v 1.132 2024/04/20 17:58:51 tom Exp $") + #if 1 #define TRACE_OUT(p) DEBUG(2, p) #define TRACE_NUM(n) if (VALID_NUMERIC(Numbers[n])) { \ @@ -50,7 +53,15 @@ #define TRACE_NUM(n) /* nothing */ #endif -MODULE_ID("$Id: write_entry.c,v 1.114 2019/06/29 23:07:18 tom Exp $") +/* + * FIXME: special case to work around Cygwin bug in link(), which updates + * the target file's timestamp. + */ +#if HAVE_LINK && !USE_SYMLINKS && !MIXEDCASE_FILENAMES && defined(__CYGWIN__) +#define LINK_TOUCHES 1 +#else +#define LINK_TOUCHES 0 +#endif static int total_written; static int total_parts; @@ -70,13 +81,13 @@ write_file(char *filename, TERMTYPE2 *tp) _nc_warning("entry is larger than %u bytes", limit); } else { FILE *fp = ((_nc_access(filename, W_OK) == 0) - ? fopen(filename, BIN_W) + ? safe_fopen(filename, BIN_W) : 0); size_t actual; if (fp == 0) { perror(filename); - _nc_syserr_abort("can't open %s/%s", _nc_tic_dir(0), filename); + _nc_syserr_abort("cannot open %s/%s", _nc_tic_dir(0), filename); } actual = fwrite(buffer, sizeof(char), (size_t) offset, fp); @@ -84,12 +95,12 @@ write_file(char *filename, TERMTYPE2 *tp) int myerr = ferror(fp) ? errno : 0; if (myerr) { _nc_syserr_abort("error writing %s/%s: %s", - _nc_tic_dir(0), + _nc_tic_dir(NULL), filename, strerror(myerr)); } else { _nc_syserr_abort("error writing %s/%s: %u bytes vs actual %lu", - _nc_tic_dir(0), + _nc_tic_dir(NULL), filename, offset, (unsigned long) actual); @@ -117,18 +128,16 @@ check_writeable(int code) char dir[sizeof(LEAF_FMT)]; char *s = 0; - if (code == 0 || (s = (strchr) (dirnames, code)) == 0) + if (code == 0 || (s = (strchr) (dirnames, code)) == 0) { _nc_err_abort("Illegal terminfo subdirectory \"" LEAF_FMT "\"", code); - - if (verified[s - dirnames]) - return; - - _nc_SPRINTF(dir, _nc_SLIMIT(sizeof(dir)) LEAF_FMT, code); - if (make_db_root(dir) < 0) { - _nc_err_abort("%s/%s: permission denied", _nc_tic_dir(0), dir); + } else if (!verified[s - dirnames]) { + _nc_SPRINTF(dir, _nc_SLIMIT(sizeof(dir)) LEAF_FMT, code); + if (make_db_root(dir) < 0) { + _nc_err_abort("%s/%s: permission denied", _nc_tic_dir(NULL), dir); + } else { + verified[s - dirnames] = TRUE; + } } - - verified[s - dirnames] = TRUE; } #endif /* !USE_HASHED_DB */ @@ -136,7 +145,7 @@ static int make_db_path(char *dst, const char *src, size_t limit) { int rc = -1; - const char *top = _nc_tic_dir(0); + const char *top = _nc_tic_dir(NULL); if (src == top || _nc_is_abs_path(src)) { if (strlen(src) + 1 <= limit) { @@ -144,7 +153,7 @@ make_db_path(char *dst, const char *src, size_t limit) rc = 0; } } else { - if (strlen(top) + strlen(src) + 2 <= limit) { + if ((strlen(top) + strlen(src) + 6) <= limit) { _nc_SPRINTF(dst, _nc_SLIMIT(limit) "%s/%s", top, src); rc = 0; } @@ -189,9 +198,9 @@ make_db_root(const char *path) #else struct stat statbuf; - if ((rc = stat(path, &statbuf)) < 0) { + if ((rc = stat(path, &statbuf)) == -1) { rc = mkdir(path -#if !defined(_WIN32) +#ifndef _NC_WINDOWS ,0777 #endif ); @@ -213,26 +222,30 @@ _nc_set_writedir(const char *dir) { const char *destination; char actual[PATH_MAX]; + bool specific = (dir != NULL); - if (dir == 0 -#ifndef USE_ROOT_ENVIRON - && use_terminfo_vars() -#endif - ) + if (!specific && use_terminfo_vars()) dir = getenv("TERMINFO"); - if (dir != 0) + if (dir != NULL) (void) _nc_tic_dir(dir); - destination = _nc_tic_dir(0); + destination = _nc_tic_dir(NULL); if (make_db_root(destination) < 0) { - char *home = _nc_home_terminfo(); + bool success = FALSE; + + if (!specific) { + char *home = _nc_home_terminfo(); - if (home != 0) { - destination = home; - if (make_db_root(destination) < 0) - _nc_err_abort("%s: permission denied (errno %d)", - destination, errno); + if (home != NULL) { + destination = home; + if (make_db_root(destination) == 0) + success = TRUE; + } + } + if (!success) { + _nc_err_abort("%s: permission denied (errno %d)", + destination, errno); } } @@ -244,10 +257,10 @@ _nc_set_writedir(const char *dir) make_db_path(actual, destination, sizeof(actual)); #else if (chdir(_nc_tic_dir(destination)) < 0 - || getcwd(actual, sizeof(actual)) == 0) + || getcwd(actual, sizeof(actual)) == NULL) _nc_err_abort("%s: not a directory", destination); #endif - _nc_keep_tic_dir(strdup(actual)); + _nc_keep_tic_dir(actual); } /* @@ -326,8 +339,9 @@ _nc_write_entry(TERMTYPE2 *const tp) if (ptr != name_list) { *ptr = '\0'; - for (ptr = name_list; *ptr != '\0' && *ptr != '|'; ptr++) - continue; + for (ptr = name_list; *ptr != '\0' && *ptr != '|'; ptr++) { + /* EMPTY */ ; + } if (*ptr == '\0') other_names = ptr; @@ -344,10 +358,10 @@ _nc_write_entry(TERMTYPE2 *const tp) #if USE_HASHED_DB if (_nc_write_object(tp, buffer + 1, &offset, limit - 1) != ERR) { - DB *capdb = _nc_db_open(_nc_tic_dir(0), TRUE); + DB *capdb = _nc_db_open(_nc_tic_dir(NULL), TRUE); DBT key, data; - if (capdb != 0) { + if (capdb != NULL) { buffer[0] = 0; memset(&key, 0, sizeof(key)); @@ -370,7 +384,7 @@ _nc_write_entry(TERMTYPE2 *const tp) sizeof(buffer) - 1); data.size = name_size + 1; - total_size += data.size; + total_size += (int) data.size; total_parts++; _nc_db_put(capdb, &key, &data); @@ -386,7 +400,7 @@ _nc_write_entry(TERMTYPE2 *const tp) key.data = ptr; key.size = strlen(ptr); - total_size += data.size; + total_size += (int) data.size; total_parts++; _nc_db_put(capdb, &key, &data); } @@ -441,10 +455,10 @@ _nc_write_entry(TERMTYPE2 *const tp) write_file(filename, tp); if (start_time == 0) { - if (stat(filename, &statbuf) < 0 + if (stat(filename, &statbuf) == -1 || (start_time = statbuf.st_mtime) == 0) { _nc_syserr_abort("error obtaining time from %s/%s", - _nc_tic_dir(0), filename); + _nc_tic_dir(NULL), filename); } } while (*other_names != '\0') { @@ -459,7 +473,7 @@ _nc_write_entry(TERMTYPE2 *const tp) _nc_warning("terminal alias %s too long.", ptr); continue; } - if (strchr(ptr, '/') != 0) { + if (strchr(ptr, '/') != NULL) { _nc_warning("cannot link alias %s.", ptr); continue; } @@ -471,10 +485,14 @@ _nc_write_entry(TERMTYPE2 *const tp) if (strcmp(filename, linkname) == 0) { _nc_warning("self-synonym ignored"); - } else if (stat(linkname, &statbuf) >= 0 && - statbuf.st_mtime < start_time) { + } +#if !LINK_TOUCHES + else if (stat(linkname, &statbuf) >= 0 && + statbuf.st_mtime < start_time) { _nc_warning("alias %s multiply defined.", ptr); - } else if (_nc_access(linkname, W_OK) == 0) + } +#endif + else if (_nc_access(linkname, W_OK) == 0) #if HAVE_LINK { int code; @@ -513,9 +531,9 @@ _nc_write_entry(TERMTYPE2 *const tp) write_file(linkname, tp); else { #if MIXEDCASE_FILENAMES - _nc_syserr_abort("can't link %s to %s", filename, linkname); + _nc_syserr_abort("cannot link %s to %s", filename, linkname); #else - _nc_warning("can't link %s to %s (errno=%d)", filename, + _nc_warning("cannot link %s to %s (errno=%d)", filename, linkname, errno); #endif } @@ -711,7 +729,7 @@ _nc_write_object(TERMTYPE2 *tp, char *buffer, unsigned *offset, unsigned limit) unsigned last_str = STRWRITE; #if NCURSES_EXT_NUMBERS bool need_ints = FALSE; - size_t (*convert_numbers) (unsigned char *, NCURSES_INT2 *, size_t) = convert_32bit; + size_t (*convert_numbers) (unsigned char *, NCURSES_INT2 *, size_t); #else #define convert_numbers convert_shorts #endif @@ -772,7 +790,8 @@ _nc_write_object(TERMTYPE2 *tp, char *buffer, unsigned *offset, unsigned limit) #else LITTLE_ENDIAN(buf, MAGIC); #endif - LITTLE_ENDIAN(buf + 2, min(namelen, MAX_NAME_SIZE + 1)); + namelen = Min(namelen, MAX_NAME_SIZE + 1); + LITTLE_ENDIAN(buf + 2, namelen); LITTLE_ENDIAN(buf + 4, boolmax); LITTLE_ENDIAN(buf + 6, nummax); LITTLE_ENDIAN(buf + 8, strmax);