diff options
Diffstat (limited to 'ncurses/tinfo/write_entry.c')
| -rw-r--r-- | ncurses/tinfo/write_entry.c | 76 |
1 files changed, 47 insertions, 29 deletions
diff --git a/ncurses/tinfo/write_entry.c b/ncurses/tinfo/write_entry.c index 8ccca9eca6fc..eddae7fbaece 100644 --- a/ncurses/tinfo/write_entry.c +++ b/ncurses/tinfo/write_entry.c @@ -1,5 +1,5 @@ /**************************************************************************** - * Copyright 2018-2023,2024 Thomas E. Dickey * + * Copyright 2018-2024,2025 Thomas E. Dickey * * Copyright 1998-2016,2017 Free Software Foundation, Inc. * * * * Permission is hereby granted, free of charge, to any person obtaining a * @@ -42,7 +42,7 @@ #include <tic.h> -MODULE_ID("$Id: write_entry.c,v 1.132 2024/04/20 17:58:51 tom Exp $") +MODULE_ID("$Id: write_entry.c,v 1.144 2025/12/28 00:33:30 tom Exp $") #if 1 #define TRACE_OUT(p) DEBUG(2, p) @@ -71,7 +71,7 @@ static int make_db_root(const char *); #if !USE_HASHED_DB static void -write_file(char *filename, TERMTYPE2 *tp) +write_file(const char *filename, TERMTYPE2 *tp) { char buffer[MAX_ENTRY_SIZE]; unsigned limit = sizeof(buffer); @@ -82,21 +82,25 @@ write_file(char *filename, TERMTYPE2 *tp) } else { FILE *fp = ((_nc_access(filename, W_OK) == 0) ? safe_fopen(filename, BIN_W) - : 0); + : NULL); size_t actual; - if (fp == 0) { - perror(filename); - _nc_syserr_abort("cannot open %s/%s", _nc_tic_dir(0), filename); + if (fp == NULL) { + _nc_syserr_abort("cannot open %s/%s: (errno %d) %s", + _nc_tic_dir(NULL), + filename, + errno, + strerror(errno)); } actual = fwrite(buffer, sizeof(char), (size_t) offset, fp); if (actual != offset) { int myerr = ferror(fp) ? errno : 0; if (myerr) { - _nc_syserr_abort("error writing %s/%s: %s", + _nc_syserr_abort("error writing %s/%s: (errno %d) %s", _nc_tic_dir(NULL), filename, + myerr, strerror(myerr)); } else { _nc_syserr_abort("error writing %s/%s: %u bytes vs actual %lu", @@ -125,15 +129,19 @@ check_writeable(int code) static const char dirnames[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; static bool verified[sizeof(dirnames)]; - char dir[sizeof(LEAF_FMT)]; - char *s = 0; + const char *s = NULL; - if (code == 0 || (s = (strchr) (dirnames, code)) == 0) { - _nc_err_abort("Illegal terminfo subdirectory \"" LEAF_FMT "\"", code); + if (code == 0 || (s = (strchr) (dirnames, code)) == NULL) { + _nc_err_abort("Illegal terminfo subdirectory \"" LEAF_FMT "\"", UChar(code)); } else if (!verified[s - dirnames]) { - _nc_SPRINTF(dir, _nc_SLIMIT(sizeof(dir)) LEAF_FMT, code); + char dir[sizeof(LEAF_FMT)]; + _nc_SPRINTF(dir, _nc_SLIMIT(sizeof(dir)) LEAF_FMT, UChar(code)); if (make_db_root(dir) < 0) { - _nc_err_abort("%s/%s: permission denied", _nc_tic_dir(NULL), dir); + _nc_err_abort("%s/%s: (errno %d) %s", + _nc_tic_dir(NULL), + dir, + errno, + strerror(errno)); } else { verified[s - dirnames] = TRUE; } @@ -153,8 +161,12 @@ make_db_path(char *dst, const char *src, size_t limit) rc = 0; } } else { - if ((strlen(top) + strlen(src) + 6) <= limit) { - _nc_SPRINTF(dst, _nc_SLIMIT(limit) "%s/%s", top, src); + size_t len_top = strlen(top); + size_t len_src = strlen(src); + if ((len_top + len_src + 6) <= limit) { + _nc_SPRINTF(dst, _nc_SLIMIT(limit) "%.*s/%.*s", + (int) len_top, top, + (int) len_src, src); rc = 0; } } @@ -186,6 +198,7 @@ make_db_root(const char *path) int rc; char fullpath[PATH_MAX]; + FixupPathname(path); if ((rc = make_db_path(fullpath, path, sizeof(fullpath))) == 0) { #if USE_HASHED_DB DB *capdbp; @@ -198,15 +211,17 @@ make_db_root(const char *path) #else struct stat statbuf; - if ((rc = stat(path, &statbuf)) == -1) { + rc = 0; + if (!_nc_is_path_found(path, &statbuf)) { rc = mkdir(path -#ifndef _NC_WINDOWS +#ifndef _NC_WINDOWS_NATIVE ,0777 #endif ); } else if (_nc_access(path, R_OK | W_OK | X_OK) < 0) { rc = -1; /* permission denied */ } else if (!(S_ISDIR(statbuf.st_mode))) { + errno = ENOTDIR; rc = -1; /* not a directory */ } #endif @@ -244,8 +259,10 @@ _nc_set_writedir(const char *dir) } } if (!success) { - _nc_err_abort("%s: permission denied (errno %d)", - destination, errno); + _nc_err_abort("%s: (errno %d) %s", + destination, + errno, + strerror(errno)); } } @@ -256,6 +273,7 @@ _nc_set_writedir(const char *dir) #if USE_HASHED_DB make_db_path(actual, destination, sizeof(actual)); #else + FixupPathname2(destination, actual); if (chdir(_nc_tic_dir(destination)) < 0 || getcwd(actual, sizeof(actual)) == NULL) _nc_err_abort("%s: not a directory", destination); @@ -431,7 +449,7 @@ _nc_write_entry(TERMTYPE2 *const tp) * so warn the user. */ if (start_time > 0 && - stat(filename, &statbuf) >= 0 + _nc_is_path_found(filename, &statbuf) && statbuf.st_mtime >= start_time) { #if HAVE_LINK && !USE_SYMLINKS /* @@ -455,7 +473,7 @@ _nc_write_entry(TERMTYPE2 *const tp) write_file(filename, tp); if (start_time == 0) { - if (stat(filename, &statbuf) == -1 + if (!_nc_is_path_found(filename, &statbuf) || (start_time = statbuf.st_mtime) == 0) { _nc_syserr_abort("error obtaining time from %s/%s", _nc_tic_dir(NULL), filename); @@ -480,14 +498,14 @@ _nc_write_entry(TERMTYPE2 *const tp) check_writeable(ptr[0]); _nc_SPRINTF(linkname, _nc_SLIMIT(sizeof(linkname)) - LEAF_FMT "/%.*s", ptr[0], + LEAF_FMT "/%.*s", UChar(ptr[0]), (int) sizeof(linkname) - (2 + LEAF_LEN), ptr); if (strcmp(filename, linkname) == 0) { _nc_warning("self-synonym ignored"); } #if !LINK_TOUCHES - else if (stat(linkname, &statbuf) >= 0 && + else if (_nc_is_path_found(linkname, &statbuf) && statbuf.st_mtime < start_time) { _nc_warning("alias %s multiply defined.", ptr); } @@ -552,7 +570,7 @@ static size_t fake_write(char *dst, unsigned *offset, size_t limit, - char *src, + const char *src, size_t want, size_t size) { @@ -658,7 +676,7 @@ convert_32bit(unsigned char *buf, NCURSES_INT2 *Numbers, size_t count) #if NCURSES_XNAMES static unsigned -extended_Booleans(TERMTYPE2 *tp) +extended_Booleans(const TERMTYPE2 *tp) { unsigned result = 0; unsigned i; @@ -671,7 +689,7 @@ extended_Booleans(TERMTYPE2 *tp) } static unsigned -extended_Numbers(TERMTYPE2 *tp) +extended_Numbers(const TERMTYPE2 *tp) { unsigned result = 0; unsigned i; @@ -684,7 +702,7 @@ extended_Numbers(TERMTYPE2 *tp) } static unsigned -extended_Strings(TERMTYPE2 *tp) +extended_Strings(const TERMTYPE2 *tp) { unsigned short result = 0; unsigned short i; @@ -701,7 +719,7 @@ extended_Strings(TERMTYPE2 *tp) * clause - discard the unneeded data. */ static bool -extended_object(TERMTYPE2 *tp) +extended_object(const TERMTYPE2 *tp) { bool result = FALSE; |
