C-Menu 0.2.9
A User Interface Toolkit
Loading...
Searching...
No Matches
Utility functions

string manipulation, file handling, and error reporting. More...

Functions

size_t trim (char *s)
 Trims leading and trailing spaces from string s in place.
size_t ssnprintf (char *buf, size_t buf_size, const char *format,...)
 ssnprintf was designed to be a safer alternative to snprintf.
int str_to_args (char **argv, char *arg_str, int max_args)
 Converts a string into an array of argument strings.
void destroy_argv (int argc, char **argv)
 Deallocates memory allocated for argument strings in argv.
bool str_to_lower (char *s)
 Converts a string to lowercase.
bool str_to_upper (char *s)
 Converts a string to uppercase.
size_t strnz__cpy (char *d, const char *s, size_t max_len)
 safer alternative to strncpy
size_t strnz__cat (char *d, const char *s, size_t max_len)
 safer alternative to strncat
size_t strz (char *s)
 Terminates string at new line or carriage return.
size_t strnz (char *s, size_t max_len)
 terminates string at New Line, Carriage Return, or max_len
size_t strnlf (char *s, size_t max_len)
 terminates string with line feed
char * strnz_dup (char *s, size_t l)
 Allocates memory for and duplicates string s up to length l or until line feed or carriage return.
bool str_subc (char *d, char *s, char ReplaceChr, char *Withstr, int l)
 Replaces "ReplaceChr" in "s" with "Withstr" in "d" won't copy more than "l" bytes to "d" Replaces all occurrences of a character in a string with another string, copying the result to a destination buffer.
bool strnfill (char *s, char c, int n)
 Fills string s with character c n.
bool strip_quotes (char *s)
 removes leading and trailing double quotes if present
bool stripz_quotes (char *s)
 removes leading and trailing double quotes if present
bool chrep (char *s, char old_chr, char new_chr)
 Replaces all occurrences of old_chr in s with new_chr in place.
int a_toi (char *s, bool *a_toi_error)
 a safer alternative to atoi() for converting ASCII strings to integers.
size_t strip_ansi (char *d, char *s)
 Strips ANSI SGR escape sequences (ending in 'm') from string s to d.
bool normalize_file_spec (char *fs)
 replace backslashes with forward lashes
bool file_spec_path (char *fp, char *fs)
 extracts the path component of a file specification
bool file_spec_name (char *fn, char *fs)
 extracts the file name component of a file specification
double str_to_double (char *s)
 converts string to double
bool expand_tilde (char *path, int path_maxlen)
 Replace Leading Tilde With Home Directory.
bool trim_path (char *dir)
 Trims trailing spaces and slashes from directory path in place.
bool trim_ext (char *buf, char *filename)
 trims the file extension from "filename" and copies the result to "buf"
bool base_name (char *buf, char *path)
 Returns the base name of a file specification.
bool dir_name (char *buf, char *path)
 Returns the directory name of a file specification.
bool verify_dir (char *spec, int imode)
 Verifies that the directory specified by "spec" exists and is accessible with the permissions specified by "imode".
bool verify_file (char *in_spec, int imode)
 Verifies that the file specified by "in_spec" exists and is accessible with the permissions specified by "imode".
bool locate_file_in_path (char *file_spec, char *file_name)
 Locates a file in the system PATH.
bool lf_find (const char *base_path, const char *re, const char *ere, int max_depth, int flags)
 Find files in a directory matching a regular expression.
bool lf_process (const char *base_path, regex_t *compiled_re, regex_t *compiled_ere, int depth, int max_depth, int flags)
 logic for lf_find()
bool mk_dir (char *dir)
 If directory doesn't exist, make it.
size_t canonicalize_file_spec (char *spec)
 Removes quotes and trims at first space.
bool is_directory (const char *path)
 Checks if the given path is a directory.
bool is_valid_regex (const char *pattern)
 Checks if the given regular expression pattern is valid.
char * rep_substring (const char *org_s, const char *tgt_s, const char *rep_s)
 Replace all occurrences of "tgt_s" in "org_s" with "rep_s".

Detailed Description

string manipulation, file handling, and error reporting.

These functions provide common operations such as trimming strings, converting case, safely copying and concatenating strings, verifying file and directory access, and locating files in the system PATH. They are designed to be robust and handle edge cases gracefully, making them useful for a wide range of applications.

Function Documentation

◆ a_toi()

int a_toi ( char * s,
bool * a_toi_error )

a safer alternative to atoi() for converting ASCII strings to integers.

Parameters
sis the input string
a_toi_erroris a pointer to a boolean that will be set to true if an error occurs during conversion, or false if the conversion is successful.
Note
accepts positive integers only.
sets a_toi_error to (-1) on error
Returns
converted integer value, or -1 if an error occurs

Definition at line 505 of file futil.c.

505 {
506 int rc = -1;
507 *a_toi_error = false;
508 errno = 0;
509 if (s && *s != 0)
510 rc = (int)strtol(s, nullptr, 10);
511 if (rc < 0 || errno) {
512 rc = -1;
513 *a_toi_error = true;
514 }
515 return rc;
516}

Referenced by parse_ansi_str().

Here is the caller graph for this function:

◆ base_name()

bool base_name ( char * buf,
char * path )

Returns the base name of a file specification.

Parameters
buf- buffer to receive result
path- file specification
Returns
true if successful
Note
The caller is responsible for ensuring that "buf" has enough space to receive the result.

Definition at line 775 of file futil.c.

776 {
777 if (!path || !*path || !buf)
778 return false;
779 char *s = path;
780 char *d = buf;
781 *d = '\0';
782 while (*s) {
783 if (*s == '/' || *s == '\\') {
784 d = buf;
785 } else {
786 *d++ = *s;
787 }
788 s++;
789 }
790 *d = '\0';
791 if (d == buf)
792 return false;
793 return true;

Referenced by build_prompt(), exec_objects(), form_process(), init_form_files(), init_pick_files(), main(), and view_init_input().

Here is the caller graph for this function:

◆ canonicalize_file_spec()

size_t canonicalize_file_spec ( char * spec)

Removes quotes and trims at first space.

Parameters
spec- file specification to canonicalize
Returns
length of resulting string

Definition at line 1216 of file futil.c.

1217 {
1218 if (spec == nullptr || *spec == '\0')
1219 return 0;
1220 char tmp_s[MAXLEN];
1221 char *s;
1222 s = spec;
1223 char *d;
1224 d = tmp_s;
1225 int l = 0;
1226 while (*s != '\0') {
1227 if (*s == ' ')
1228 break;
1229 if (*s == '\"' || *s == '\'') {
1230 s++;
1231 continue;
1232 ;
1233 }
1234 *d++ = *s++;
1235 l++;
1236 }
1237 *d = '\0';
1238 strnz__cpy(spec, tmp_s, MAXLEN - 1);
1239 l = strlen(spec);
1240 return l;
#define MAXLEN
Definition curskeys.c:15
size_t strnz__cpy(char *, const char *, size_t)
safer alternative to strncpy
Definition futil.c:269

References strnz__cpy().

Referenced by locate_file_in_path(), verify_file(), and verify_spec_arg().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ chrep()

bool chrep ( char * s,
char old_chr,
char new_chr )

Replaces all occurrences of old_chr in s with new_chr in place.

Parameters
s- string to modify
old_chr- character to replace
new_chr- character to insert
Returns
true if successful or false if string s is null

Definition at line 486 of file futil.c.

486 {
487 if (s == nullptr)
488 return false;
489 while (*s != '\0') {
490 if (*s == old_chr)
491 *s = new_chr;
492 s++;
493 }
494 return true;
495}

Referenced by parse_menu_description().

Here is the caller graph for this function:

◆ destroy_argv()

void destroy_argv ( int argc,
char ** argv )

Deallocates memory allocated for argument strings in argv.

Parameters
argc- count of allocated vectors in argv
argv- array of pointers to arguments
Note
the caller must ensure that argc accurately reflects the number of allocated strings in argv, and that argv is not null. After calling this function, the pointers in argv will be set to nullptr to prevent dangling pointers.

Definition at line 221 of file futil.c.

221 {
222 for (int i = 0; i < argc; i++) {
223 if (argv[i] != nullptr) {
224 free(argv[i]);
225 argv[i] = nullptr;
226 }
227 }
228}

Referenced by destroy_init(), destroy_view(), display_pick_help(), enter_file_spec(), exec_objects(), form_engine(), form_process(), init_pick(), menu_cmd_processor(), view_display_help(), and view_init_input().

Here is the caller graph for this function:

◆ dir_name()

bool dir_name ( char * buf,
char * path )

Returns the directory name of a file specification.

Parameters
buf- buffer to receive result
path- file specification
Returns
true if successful
Note
The caller is responsible for ensuring that "buf" has enough space to receive the result.

Definition at line 801 of file futil.c.

802 {
803 if (!path || !*path || !buf)
804 return false;
805 char tmp_str[MAXLEN];
806 strnz__cpy(tmp_str, path, MAXLEN);
807 char *s = tmp_str;
808 while (*s++)
809 ;
810 while (tmp_str < --s) {
811 if (*s == '/' || *s == '\\') {
812 *s = '\0';
813 break;
814 }
815 }
816 while (tmp_str < --s && (*s == '/' || *s == '\\'))
817 *s = '\0';
818 char *d = buf;
819 *d = '\0';
820 s = tmp_str;
821 while (*s) {
822 *d++ = *s++;
823 }
824 *d = '\0';
825 if (d == buf)
826 return false;
827 return true;

References strnz__cpy().

Here is the call graph for this function:

◆ expand_tilde()

bool expand_tilde ( char * path,
int path_maxlen )

Replace Leading Tilde With Home Directory.

Parameters
path- path to expand
path_maxlen- maximum length of path
Note
The caller is responsible for ensuring that "path" has enough space to receive the result, and that "path_maxlen" is sufficient to hold the result. This function does not perform any bounds checking on "path", so it is the caller's responsibility to ensure that it is valid and that "path_maxlen" is appropriate for the operation.
Returns
true if successful

Definition at line 684 of file futil.c.

685 {
686 if (path == nullptr || *path == '\0' || path_maxlen == 0)
687 return false;
688 char *e;
689 char ts[MAXLEN];
690 char *tp;
691
692 if (!path || !*path || !path_maxlen)
693 return false;
694 tp = path;
695 if (*tp == '~') {
696 tp++;
697 while (*tp == '/') {
698 tp++;
699 }
700 e = getenv("HOME");
701 if (e) {
702 strnz__cpy(ts, e, path_maxlen - 1);
703 strnz__cat(ts, "/", path_maxlen - 1);
704 strnz__cat(ts, tp, path_maxlen - 1);
705 strnz__cpy(path, ts, path_maxlen - 1);
706 }
707 }
708 return true;
size_t strnz__cat(char *, const char *, size_t)
safer alternative to strncat
Definition futil.c:298

References strnz__cat(), and strnz__cpy().

Referenced by enter_file_spec(), mapp_initialization(), mk_dir(), parse_config(), verify_dir(), verify_file(), verify_spec_arg(), and view_init_input().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ file_spec_name()

bool file_spec_name ( char * fn,
char * fs )

extracts the file name component of a file specification

Parameters
fn- name component to return
fs- full file specification
Note
The caller is responsible for ensuring that "fn" has enough space to receive the result.

Definition at line 605 of file futil.c.

606 {
607 if (fs == nullptr || *fs == '\0' || fn == nullptr) {
608 if (fn != nullptr)
609 *fn = '\0';
610 return false;
611 }
612 char *d, *l, *s;
613 l = nullptr;
614 s = fs;
615 while (*s != '\0') {
616 if (*s == '/')
617 l = s;
618 s++;
619 }
620 if (l == nullptr)
621 s = fs;
622 else
623 s = ++l;
624 d = fn;
625 while (*s != '\0')
626 *d++ = *s++;
627 *d = '\0';
628 return true;
char fn[MAXLEN]
Definition dwin.c:131

◆ file_spec_path()

bool file_spec_path ( char * fp,
char * fs )

extracts the path component of a file specification

Parameters
fp- path component to return
fs- full file specification
Returns
true if successful
Note
The caller is responsible for ensuring that "fp" has enough space to receive the result.

Definition at line 578 of file futil.c.

579 {
580 if (fs == nullptr || *fs == '\0' || fp == nullptr) {
581 if (fp != nullptr)
582 *fp = '\0';
583 return false;
584 }
585 char *d, *l, *s;
586 s = fp;
587 d = fs;
588 l = nullptr;
589 while (*s != '\0') {
590 if (*s == '/')
591 l = d;
592 *d++ = *s++;
593 }
594 if (l == nullptr)
595 *fp = '\0'; // no slash, so no path
596 else
597 *l = '\0';
598 return true;

◆ is_directory()

bool is_directory ( const char * path)

Checks if the given path is a directory.

Parameters
path- path to check
Returns
true if the path is a directory, false otherwise

Definition at line 1245 of file futil.c.

1246 {
1247 struct stat statbuf;
1248 if (stat(path, &statbuf) != 0) {
1249 return false;
1250 }
1251 return S_ISDIR(statbuf.st_mode);

Referenced by main().

Here is the caller graph for this function:

◆ is_valid_regex()

bool is_valid_regex ( const char * pattern)

Checks if the given regular expression pattern is valid.

Parameters
pattern- regular expression pattern to check
Returns
true if the pattern is valid, false otherwise

Definition at line 1256 of file futil.c.

1257 {
1258 regex_t regex;
1259 int ret = regcomp(&regex, pattern, REG_EXTENDED);
1260 regfree(&regex);
1261 return (ret == 0);

Referenced by main().

Here is the caller graph for this function:

◆ lf_find()

bool lf_find ( const char * base_path,
const char * re,
const char * ere,
int max_depth,
int flags )

Find files in a directory matching a regular expression.

Parameters
base_pathdirectory to search
ereregular expression match to exclude
reregular expression match to include
max_depthdepth of directories to scan
flagssearch flags
See also
lf_process() for flag definitions return true if successful, false otherwise

Definition at line 977 of file futil.c.

979 {
980 int reti;
981 regex_t compiled_re;
982 regex_t compiled_ere;
983 int REG_FLAGS = REG_EXTENDED;
984 if (flags & LF_ICASE)
985 REG_FLAGS |= REG_ICASE;
986 if (flags & LF_REGEX) {
987 reti = regcomp(&compiled_re, re, REG_FLAGS);
988 if (reti) {
989 ssnprintf(em0, MAXLEN - 1, "lf: \'%s\' Invalid pattern\n", re);
990 ssnprintf(em1, MAXLEN - 1, "for example: \'.*\\.c$\'\n\n");
991 regerror(reti, &compiled_re, em2, sizeof(em2));
992 display_error(em0, em1, em2, nullptr);
993 regfree(&compiled_re);
994 return false;
995 }
996 }
997 if (flags & LF_EXC_REGEX) {
998 regcomp(&compiled_ere, "^$", REG_FLAGS);
999 reti = regcomp(&compiled_ere, ere, REG_FLAGS);
1000 if (reti) {
1001 ssnprintf(em0, MAXLEN - 1, "lf: \'%s\' Invalid exclude pattern\n",
1002 re);
1003 ssnprintf(em1, MAXLEN - 1, "for example: \'.*\\.c$\'\n\n");
1004 regerror(reti, &compiled_ere, em2, sizeof(em2));
1005 display_error(em0, em1, em2, nullptr);
1006 regfree(&compiled_ere);
1007 return false;
1008 }
1009 }
1010 reti =
1011 lf_process(base_path, &compiled_re, &compiled_ere, 0, max_depth, flags);
1012 if (flags &= LF_REGEX)
1013 regfree(&compiled_re);
1014 if (flags & LF_EXC_REGEX)
1015 regfree(&compiled_ere);
1016 if (reti)
1017 return false;
1018 return true;
@ LF_EXC_REGEX
Definition cm.h:151
@ LF_ICASE
Definition cm.h:150
@ LF_REGEX
Definition cm.h:152
char em1[MAXLEN]
Definition dwin.c:133
char em0[MAXLEN]
Definition dwin.c:132
char em2[MAXLEN]
Definition dwin.c:134
int display_error(char *em0, char *em1, char *em2, char *em3)
Display an error message window or print to stderr.
Definition dwin.c:1054
bool lf_process(const char *, regex_t *, regex_t *, int, int, int)
logic for lf_find()
Definition futil.c:1063
size_t ssnprintf(char *, size_t, const char *,...)
ssnprintf was designed to be a safer alternative to snprintf.
Definition futil.c:147

References display_error(), em0, em1, em2, LF_EXC_REGEX, LF_ICASE, lf_process(), LF_REGEX, and ssnprintf().

Referenced by main().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ lf_process()

bool lf_process ( const char * base_path,
regex_t * compiled_re,
regex_t * compiled_ere,
int depth,
int max_depth,
int flags )

logic for lf_find()

Parameters
base_pathdirectory to search
compiled_erecompiled regular expression to exclude
compiled_recompiled regular expression to include
depthrecursion counter
max_depthhow deep to descend into the directory structure
flags
Returns
true if successful, false otherwise
LF_ALL = 1,       List all files including hidden files
LF_ICASE = 2,     Ignore case in search
LF_EXC_REGEX = 4, Exclude files matching regular expression
LF_REGEX = 8,     Include files matching regular expression
LF_BLK = 256,
LF_CHR = 512,
LF_DIR = 1024,
LF_FIFO = 2048,
LF_LNK = 4096,
LF_REG = 8192,
LF_SOCK = 16384,
LF_UNKNOWN = 32768,
                  Include     Exclude
                 ----------  ----------
LF_BLK        1  0 00000001  7 11111110 block device
LF_CHR        2  1 00000010  6 11111101 character device
LF_DIR        4  2 00000100  5 11111011 directory
LF_FIFO       8  3 00001000  4 11110111 named pipe
LF_LNK       16  4 00010000  3 11101111 link
LF_REG       32  5 00100000  2 11011111 regular file
LF_SOCK      64  6 01000000  1 10111111 socket
LF_UNKNOWN  128  7 10000000  0 01111111 unknown

bool s_blk;
bool s_chr;
bool s_dir;
bool s_fifo;
bool s_lnk;
bool s_reg;
bool s_sock;
bool s_unknown;

Definition at line 1063 of file futil.c.

1065 {
1066 char tmp_str[MAXLEN];
1067 struct dirent *dir_st;
1068 DIR *dir;
1069 int REG_FLAGS = REG_EXTENDED;
1070 int reti;
1071 regmatch_t pmatch[1];
1072 char file_spec[1024];
1073 bool suppress;
1074 int f_include;
1075 int f_suppress;
1076 bool suppress_hidden = flags & LF_HIDE ? true : false;
1077 char bname[MAXLEN];
1078 if ((dir = opendir(base_path)) == 0)
1079 return false;
1080 while ((dir_st = readdir(dir)) != nullptr) {
1081 strnz__cpy(bname, dir_st->d_name, MAXLEN - 1);
1082 if (bname[0] == '.' && bname[1] == '\0')
1083 continue;
1084 else if (bname[0] == '.' && bname[1] == '.' && bname[2] == '\0')
1085 continue;
1086 else if (bname[0] == '.' && suppress_hidden)
1087 continue;
1088 f_suppress = 0;
1089 f_include = (flags >> 8) & 0xff;
1090 if (f_include)
1091 f_suppress = f_include ^ 0xff;
1092 bool s_blk = f_suppress & FT_BLK ? 1 : 0;
1093 bool s_chr = f_suppress & FT_CHR ? 1 : 0;
1094 bool s_dir = f_suppress & FT_DIR ? 1 : 0;
1095 bool s_fifo = f_suppress & FT_FIFO ? 1 : 0;
1096 bool s_lnk = f_suppress & FT_LNK ? 1 : 0;
1097 bool s_reg = f_suppress & FT_REG ? 1 : 0;
1098 bool s_sock = f_suppress & FT_SOCK ? 1 : 0;
1099 bool s_unknown = f_suppress & FT_UNKNOWN ? 1 : 0;
1100 suppress = false;
1101 switch (dir_st->d_type) {
1102 case DT_BLK:
1103 if (s_blk)
1104 suppress = true;
1105 break;
1106 case DT_CHR:
1107 if (s_chr)
1108 suppress = true;
1109 break;
1110 case DT_DIR:
1111 if (s_dir)
1112 suppress = true;
1113 break;
1114 case DT_FIFO:
1115 if (s_fifo)
1116 suppress = true;
1117 break;
1118 case DT_LNK:
1119 if (s_lnk)
1120 suppress = true;
1121 break;
1122 case DT_REG:
1123 if (s_reg)
1124 suppress = true;
1125 break;
1126 case DT_SOCK:
1127 if (s_sock)
1128 suppress = true;
1129 break;
1130 case DT_UNKNOWN:
1131 if (s_unknown)
1132 suppress = true;
1133 break;
1134 default:
1135 break;
1136 }
1137 if (dir_st->d_name[0] == '.' && dir_st->d_name[1] == '/')
1138 strnz__cpy(file_spec, &dir_st->d_name[2], MAXLEN - 1);
1139 else
1140 strnz__cpy(file_spec, dir_st->d_name, MAXLEN - 1);
1141 ssnprintf(file_spec, sizeof(file_spec), "%s/%s", base_path, bname);
1142 if (bname[0] == '.' && suppress_hidden)
1143 suppress = true;
1144 if (!suppress && (flags & LF_REGEX)) {
1145 reti = regexec(compiled_re, file_spec, compiled_re->re_nsub + 1,
1146 pmatch, REG_FLAGS);
1147 if (reti == REG_NOMATCH) {
1148 suppress = true;
1149 } else if (reti) {
1150 char msgbuf[100];
1151 regerror(reti, compiled_re, msgbuf, sizeof(msgbuf));
1152 strnz__cpy(tmp_str, "Regex match failed: ", MAXLEN - 1);
1153 strnz__cat(tmp_str, msgbuf, MAXLEN - 1);
1154 Perror(tmp_str);
1155 return false;
1156 }
1157 }
1158 if (!suppress && (flags & LF_EXC_REGEX)) {
1159 reti = regexec(compiled_ere, file_spec, compiled_re->re_nsub + 1,
1160 pmatch, REG_FLAGS);
1161 if (reti == 0)
1162 suppress = true;
1163 else if (reti == REG_NOMATCH)
1164 suppress = false;
1165 else if (reti) {
1166 char msgbuf[100];
1167 regerror(reti, compiled_re, msgbuf, sizeof(msgbuf));
1168 strnz__cpy(tmp_str, "Regex match failed: ", MAXLEN - 1);
1169 strnz__cat(tmp_str, msgbuf, MAXLEN - 1);
1170 Perror(tmp_str);
1171 return false;
1172 }
1173 }
1174
1175 if (!suppress) {
1176 if (file_spec[0] == '.' && file_spec[1] == '/')
1177 printf("%s\n", &file_spec[2]);
1178 else
1179 printf("%s\n", file_spec);
1180 }
1181 if (max_depth == 0 ||
1182 (dir_st->d_type == DT_DIR && depth + 1 < max_depth)) {
1183 depth++;
1184 lf_process(file_spec, compiled_re, compiled_ere, depth, max_depth,
1185 flags);
1186 depth--;
1187 }
1188 }
1189 closedir(dir);
1190 return true;
@ FT_UNKNOWN
Definition cm.h:164
@ FT_SOCK
Definition cm.h:163
@ FT_DIR
Definition cm.h:159
@ FT_FIFO
Definition cm.h:160
@ FT_REG
Definition cm.h:162
@ FT_CHR
Definition cm.h:158
@ FT_BLK
Definition cm.h:157
@ FT_LNK
Definition cm.h:161
@ LF_HIDE
Definition cm.h:149
int Perror(char *)
Display a simple error message window or print to stderr.
Definition dwin.c:1110

References FT_BLK, FT_CHR, FT_DIR, FT_FIFO, FT_LNK, FT_REG, FT_SOCK, FT_UNKNOWN, LF_EXC_REGEX, LF_HIDE, lf_process(), LF_REGEX, Perror(), ssnprintf(), strnz__cat(), and strnz__cpy().

Referenced by lf_find(), and lf_process().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ locate_file_in_path()

bool locate_file_in_path ( char * file_spec,
char * file_name )

Locates a file in the system PATH.

Parameters
file_spec- buffer to receive located file specification
file_name- name of file to locate
Returns
true if file is located
Note
file_spec must be large enough to receive the result

Definition at line 939 of file futil.c.

940 {
941 if (file_name == nullptr || *file_name == '\0' || file_spec == nullptr)
942 return false;
943 char path[MAXLEN];
944 char fn[MAXLEN];
945 char *p, *fnp, *dir;
946
949 fnp = fn;
950 while (*fnp && *fnp != '/')
951 fnp++;
952 if (*fnp == '/')
953 return false;
954 if ((p = getenv("PATH")) == nullptr)
955 return false;
956 strnz__cpy(path, p, MAXLEN - 1);
957 dir = strtok(path, ":");
958 while (dir != nullptr) {
959 strnz__cpy(file_spec, dir, MAXLEN - 1);
960 strnz__cat(file_spec, "/", MAXLEN - 1);
961 strnz__cat(file_spec, file_name, MAXLEN - 1);
962 if (access(file_spec, F_OK) == 0) {
963 return true;
964 }
965 dir = strtok(nullptr, ":");
966 }
967 return false;
char * file_name[MAXLEN+1]
Definition whence.c:25
size_t canonicalize_file_spec(char *)
Removes quotes and trims at first space.
Definition futil.c:1216

References canonicalize_file_spec(), strnz__cat(), and strnz__cpy().

Referenced by init_form_files(), init_pick_files(), and verify_spec_arg().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ mk_dir()

bool mk_dir ( char * dir)

If directory doesn't exist, make it.

Parameters
dirdirectory name
Returns
true if directory now exists or false otherwise

Directory does not exist and unable to create

Definition at line 1195 of file futil.c.

1196 {
1197 expand_tilde(dir, MAXLEN - 1);
1198 if (!verify_dir(dir, S_WCOK | S_QUIET)) {
1199 if (!mkdir(dir, 0755)) {
1201 ssnprintf(em0, MAXLEN - 1, "%s, line: %d", __FILE__, __LINE__ - 2);
1202 strnz__cpy(em1, "mkdir ", MAXLEN - 1);
1203 strnz__cat(em1, dir, MAXLEN - 1);
1204 strnz__cat(em1, " failed", MAXLEN - 1);
1205 strerror_r(errno, em2, MAXLEN - 1);
1206 display_error(em0, em1, em2, nullptr);
1207 return false;
1208 }
1209 return true;
1210 }
1211 return true;
#define S_QUIET
Definition cm.h:183
#define S_WCOK
Definition cm.h:182
bool expand_tilde(char *path, int path_maxlen)
Replace Leading Tilde With Home Directory.
Definition futil.c:684
bool verify_dir(char *, int)
Verifies that the directory specified by "spec" exists and is accessible with the permissions specifi...
Definition futil.c:841

References display_error(), em0, em1, em2, expand_tilde(), ssnprintf(), strnz__cat(), strnz__cpy(), and verify_dir().

Referenced by enter_file_spec().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ normalize_file_spec()

bool normalize_file_spec ( char * fs)

replace backslashes with forward lashes

Parameters
fs- file specification to normalize
Returns
true if successful, false if fs is nullptr or empty

Definition at line 561 of file futil.c.

562 {
563 if (fs == nullptr || *fs == '\0')
564 return false;
565 while (*fs != '\0') {
566 if (*fs == '\\')
567 *fs = '/';
568 fs++;
569 }
570 return true;

◆ rep_substring()

char * rep_substring ( const char * org_s,
const char * tgt_s,
const char * rep_s )

Replace all occurrences of "tgt_s" in "org_s" with "rep_s".

Parameters
org_s- original string
tgt_s- target substring to replace
rep_s- replacement substring
Returns
A pointer to the newly allocated string with replacements or a copy of the replacement string if original string is the same as target string This is a special case that allows for replacing the entire original string. If any parameter is nullptr, the function returns nullptr. If "tgt_s" is not found in "org_s", the function returns a copy of "org_s". If target substring is not found the function returns a copy of the original string.
Note
allocates memory for the return value, so the caller is responsible for freeing this memory when it is no longer needed to avoid memory leaks.
Does not modify the original string "org_s".
Assumes that "tgt_s" and "rep_s" are null-terminated strings. If they are not, the behavior is undefined.
Does not perform any bounds checking on the input strings, so it is the caller's responsibility to ensure that they are valid and that the resulting string does not exceed available memory.
Uses the standard library functions strlen, strstr, malloc, and strcpy, which may have their own limitations and behaviors that the caller should be aware of.
Does not handle overlapping occurrences of "tgt_s" in "org_s". If "tgt_s" can overlap with itself in "org_s", the behavior may be unexpected. The caller should ensure that "tgt_s" does not contain overlapping patterns to avoid this issue.
Does not handle cases where "tgt_s" is a substring of "rep_s", which could lead to unintended consequences if "tgt_s" appears in "rep_s". The caller should ensure that "tgt_s" and "rep_s" are distinct to avoid this issue.

Definition at line 1292 of file futil.c.

1293 {
1294 if (org_s == nullptr || tgt_s == nullptr || rep_s == nullptr)
1295 return nullptr;
1296 if (*org_s == '\0' || *tgt_s == '\0' || *rep_s == '\0')
1297 return nullptr;
1298 if (strstr(org_s, tgt_s) == nullptr)
1299 return strdup(org_s);
1300 if (strstr(rep_s, tgt_s) != nullptr)
1301 return nullptr;
1302 if (tgt_s == rep_s || tgt_s == org_s || rep_s == org_s)
1303 return strdup(org_s);
1304 if (strcmp(org_s, tgt_s) == 0)
1305 return strdup(rep_s);
1306 char *out_s, *ip, *tmp;
1307 int tgt_l = strlen(tgt_s);
1308 int rep_l = strlen(rep_s);
1309 int head_l;
1310 int n = 0;
1311 ip = (char *)org_s;
1312 while ((tmp = strstr(ip, tgt_s)) != nullptr) {
1313 n++;
1314 ip = tmp + tgt_l;
1315 }
1316 out_s = malloc(strlen(org_s) + (rep_l - tgt_l) * n + 1);
1317 if (!out_s) {
1318 return nullptr;
1319 }
1320 tmp = out_s;
1321 ip = (char *)org_s;
1322 while (n--) {
1323 char *p = strstr(ip, tgt_s);
1324 head_l = p - ip;
1325 strnz__cpy(tmp, ip, head_l);
1326 tmp += head_l;
1327 strnz__cpy(tmp, rep_s, MAXLEN - 1);
1328 tmp += rep_l;
1329 ip += head_l + tgt_l;
1330 }
1331 strnz__cpy(tmp, ip, MAXLEN - 1);
1332 return out_s;

References strnz__cpy().

Referenced by exec_objects().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ ssnprintf()

size_t ssnprintf ( char * buf,
size_t buf_size,
const char * format,
... )

ssnprintf was designed to be a safer alternative to snprintf.

It ensures that the buffer is not overflowed by taking the buffer size as a parameter and using vsnprintf internally. It also returns the number of characters that would have been written if enough space had been available, allowing the caller to detect truncation. This function is particularly useful in situations where the formatted string may exceed the buffer size, as it prevents buffer overflows and provides a way to handle such cases gracefully.

Parameters
buf- buffer to receive formatted string
buf_size- size of buffer
format- printf-style format string
...- arguments
Returns
number of characters that would have been written if enough space had been available

Definition at line 147 of file futil.c.

147 {
148 size_t n;
149 va_list args;
150
151 va_start(args, format);
152 n = vsnprintf(buf, buf_size, format, args);
153 va_end(args);
154
155 return n;
156}

Referenced by action_disposition(), answer_yn(), display_error(), display_line(), enter_file_spec(), fork_exec(), form_desc_error(), form_parse_desc(), form_process(), form_write(), get_clr_pair(), handle_signal(), init_view_boxwin(), init_view_full_screen(), lf_find(), lf_process(), lp(), mapp_initialization(), menu_engine(), mk_dir(), new_init(), new_pick(), new_view(), open_pick_win(), parse_menu_description(), Perror(), search(), set_chyron_key(), set_chyron_key_cp(), signal_handler(), verify_dir(), verify_file(), view_cmd_processor(), view_init_input(), wait_continue(), wait_mk_win(), waitpid_with_timeout(), and write_view_buffer().

Here is the caller graph for this function:

◆ str_subc()

bool str_subc ( char * d,
char * s,
char ReplaceChr,
char * Withstr,
int l )

Replaces "ReplaceChr" in "s" with "Withstr" in "d" won't copy more than "l" bytes to "d" Replaces all occurrences of a character in a string with another string, copying the result to a destination buffer.

Parameters
d- destination string
s- source string
ReplaceChr- character to replace
Withstr- string to insert
l- maximum length to copy
Returns
true if successful, false if any parameter is invalid

This function ensures that the total length of the resulting string does not exceed the specified limit, and that the result is null-terminated. This function is useful for simple string substitutions where you want to replace a single character with a longer string, such as replacing spaces with underscores or tabs with spaces.

Note
The caller must ensure that "d" has enough space to receive the result, and that "l" is sufficient to hold the result. This function does not perform any bounds checking on "d" or "Withstr", so it is the caller's responsibility to ensure that they are valid and that "l" is appropriate for the operation.

Definition at line 415 of file futil.c.

415 {
416 char *e;
417 if (s == nullptr || d == nullptr || Withstr == nullptr || l == 0) {
418 if (d != nullptr && l > 0)
419 *d = '\0';
420 return false;
421 }
422 e = d + l;
423 while (*s != '\0' && d < e) {
424 if (*s == ReplaceChr) {
425 while (*Withstr != '\0' && d < e)
426 *d++ = *Withstr++;
427 s++;
428 } else
429 *d++ = *s++;
430 }
431 *d = '\0';
432 return true;
433}

Referenced by view_cmd_processor().

Here is the caller graph for this function:

◆ str_to_args()

int str_to_args ( char ** argv,
char * arg_str,
int max_args )

Converts a string into an array of argument strings.

Note
Handles quoted strings and escaped quotes, preserving text inside quotes as individual arguments. It has been in service for many years without problems.
Parameters
argv- array of pointers to arguments
arg_str- string containing arguments
max_args- maximum number of arguments to parse
Returns
argc, a count of allocated vectors in argv
Note
the caller is responsible for deallocating the strings in argv

Definition at line 167 of file futil.c.

167 {
168 if (arg_str == nullptr || *arg_str == '\0')
169 return 0;
170 int argc = 0;
171 char *p = arg_str;
172 char tmp_str[MAXLEN];
173 int in_quotes = 0;
174 char *d = tmp_str;
175
176 while (*p != '\0' && argc < max_args) {
177 while (isspace((unsigned char)*p))
178 p++;
179 if (*p == '\0')
180 break;
181 if (*p == '"') {
182 in_quotes = 1;
183 p++;
184 }
185 while (*p != '\0') {
186 if (in_quotes) {
187 if (*p == '\\' && *(p + 1) == '"') {
188 *d++ = '"';
189 p += 2;
190 } else if (*p == '"') {
191 *d++ = '\0';
192 p++;
193 in_quotes = 0;
194 break;
195 } else
196 *d++ = *p++;
197 } else {
198 if (isspace((unsigned char)*p)) {
199 *d++ = '\0';
200 p++;
201 break;
202 } else
203 *d++ = *p++;
204 }
205 }
206 *d = '\0';
207 d = tmp_str;
208 argv[argc++] = strdup(tmp_str);
209 }
210 argv[argc] = nullptr;
211 return argc;
212}

Referenced by enter_file_spec(), exec_objects(), form_process(), init_pick(), menu_cmd_processor(), and view_init_input().

Here is the caller graph for this function:

◆ str_to_double()

double str_to_double ( char * s)

converts string to double

Parameters
s- string to convert
Returns
converted double value, or 0.0 if s is nullptr, empty, or invalid
Note
The caller must ensure that the string is a valid representation of a double before calling this function.

Definition at line 637 of file futil.c.

638 {
639 char *e;
640 double d;
641
642 if (!s || !*s)
643 return false;
644 d = strtod(s, &e);
645 return d;

Referenced by parse_config().

Here is the caller graph for this function:

◆ str_to_lower()

bool str_to_lower ( char * s)

Converts a string to lowercase.

Parameters
s- string to convert
Returns
true if successful, false if s is nullptr or empty

Definition at line 233 of file futil.c.

233 {
234 if (s == nullptr || *s == '\0')
235 return false;
236 while (*s != '\0') {
237 if (*s >= 'A' && *s <= 'Z')
238 *s = *s + 'a' - 'A';
239 s++;
240 }
241 return true;
242}

Referenced by clr_name_to_idx(), and form_parse_desc().

Here is the caller graph for this function:

◆ str_to_upper()

bool str_to_upper ( char * s)

Converts a string to uppercase.

Parameters
s- string to convert
Returns
true if successful, false if s is nullptr or empty

Definition at line 247 of file futil.c.

247 {
248 if (s == nullptr || *s == '\0')
249 return false;
250 while (*s != '\0') {
251 if (*s >= 'a' && *s <= 'z')
252 *s = *s + 'A' - 'a';
253 s++;
254 }
255 return true;
256}

◆ strip_ansi()

size_t strip_ansi ( char * d,
char * s )

Strips ANSI SGR escape sequences (ending in 'm') from string s to d.

Parameters
dDestination string
sSource string
Returns
Length of stripped string
char dest[1024];
char src[] = "\033[31mThis is red text\033[0m
size_t len = strip_ansi(dest, src);
Result: dest = "This is red text", len = 17
@example stripansi.c
Note
Only handles SGR sequences ending in 'm' or 'K'
Skips non-ASCII characters
The caller must ensure that d has enough space to hold the stripped string
This function does not allocate memory; it assumes d is pre-allocated
This function processes the entire string until the null terminator
This function does not modify the source string s

Definition at line 537 of file futil.c.

538 {
539 size_t l = 0;
540 while (*s) {
541 if (*s == '\033') {
542 while (*s && *s != 'm' && *s != 'K')
543 s++;
544 if (*s == 'm' || *s == 'K')
545 s++;
546 continue;
547 } else {
548 if ((unsigned char)*s <= 127) {
549 *d++ = *s++;
550 l++;
551 } else
552 s++;
553 }
554 }
555 *d = '\0';
556 return l;

Referenced by main(), and write_view_buffer().

Here is the caller graph for this function:

◆ strip_quotes()

bool strip_quotes ( char * s)

removes leading and trailing double quotes if present

Parameters
s- string to strip quotes from
Returns
true if successful, false if s is nullptr or empty

Definition at line 454 of file futil.c.

454 {
455 if (s == nullptr)
456 return false;
457 int l = strlen(s);
458 if (l > 1 && s[l - 1] == '\"') {
459 memmove(s, s + 1, l - 2);
460 s[l - 2] = '\0';
461 }
462 return true;
463}

Referenced by init_form_files(), and init_view_files().

Here is the caller graph for this function:

◆ stripz_quotes()

bool stripz_quotes ( char * s)

removes leading and trailing double quotes if present

Parameters
s- string to strip quotes from
Returns
true if quotes were removed
Note
Same as STRIP_QUOTES but returns true if quotes were removed

Definition at line 469 of file futil.c.

469 {
470 if (s == nullptr || strlen(s) < 2)
471 return false;
472 int l = strlen(s);
473 if (l > 1 && s[0] == '\"' && s[l - 1] == '\"') {
474 memmove(s, s + 1, l - 2);
475 s[l - 2] = '\0';
476 return true;
477 }
478 return false;
479}

Referenced by verify_spec_arg().

Here is the caller graph for this function:

◆ strnfill()

bool strnfill ( char * s,
char c,
int n )

Fills string s with character c n.

Parameters
s- string to fill
c- character to fill with
n- number of characters to fill
Returns
true if successful, false if s is nullptr or n is non-positive

Definition at line 440 of file futil.c.

440 {
441 if (s == nullptr || n <= 0)
442 return false;
443 char *e;
444 e = s + n;
445 while (s < e)
446 *s++ = c;
447 *s = '\0';
448 return true;
449}

Referenced by form_display_fields().

Here is the caller graph for this function:

◆ strnlf()

size_t strnlf ( char * s,
size_t max_len )

terminates string with line feed

Parameters
sstring to terminate
max_lenmaximum length to scan
Returns
length of resulting string

Definition at line 358 of file futil.c.

358 {
359 char *e;
360 size_t len = 0;
361 if (s == nullptr || *s == '\0' || max_len == 0)
362 return 0;
363 e = s + max_len;
364 while (*s != '\0' && *s != '\n' && *s != '\r' && s < e) {
365 s++;
366 len++;
367 }
368 *s++ = '\n';
369 len++;
370 *s = '\0';
371 return (len);
372}

Referenced by write_view_buffer().

Here is the caller graph for this function:

◆ strnz()

size_t strnz ( char * s,
size_t max_len )

terminates string at New Line, Carriage Return, or max_len

Note
The use case is to ensure that strings read from files or user input do not contain embedded newlines or carriage returns.
Parameters
sstring to terminate
max_len- maximum length to scan
Returns
length of resulting string

Definition at line 340 of file futil.c.

340 {
341 char *e;
342 size_t len = 0;
343 if (s == nullptr || *s == '\0' || max_len == 0)
344 return 0;
345 e = s + max_len;
346 while (*s != '\0' && *s != '\n' && *s != '\r' && s < e) {
347 s++;
348 len++;
349 }
350 *s = '\0';
351 return (len);
352}

Referenced by answer_yn(), display_error(), enter_file_spec(), form_display_fields(), form_display_screen(), form_fmt_field(), and pick_engine().

Here is the caller graph for this function:

◆ strnz__cat()

size_t strnz__cat ( char * d,
const char * s,
size_t max_len )

safer alternative to strncat

Note
It appends string s to d, ensuring that the total length of d does not exceed max_len, and that the resulting string is null-terminated. It also treats newline and carriage return characters as string terminators, preventing them from being included in the result. This is particularly useful when concatenating user input or file data, where embedded newlines could cause issues.
Parameters
d- destination string
s- source string
max_len- maximum length to copy
Returns
length of resulting string

Definition at line 298 of file futil.c.

298 {
299 char *e;
300 size_t len = 0;
301 if (s == nullptr || d == nullptr || max_len == 0) {
302 if (d != nullptr && max_len > 0)
303 *d = '\0';
304 return 0;
305 }
306 e = d + max_len;
307 while (*d != '\0' && *d != '\n' && *d != '\r' && d < e) {
308 d++;
309 len++;
310 }
311 while (*s != '\0' && *s != '\n' && *s != '\r' && d < e) {
312 *d++ = *s++;
313 len++;
314 }
315 *d = '\0';
316 return len;
317}

Referenced by build_prompt(), derive_file_spec(), display_pick_help(), enter_file_spec(), exec_objects(), expand_tilde(), file_spec_parts(), form_display_screen(), form_engine(), form_exec_cmd(), form_parse_desc(), form_process(), form_read_data(), form_write(), init_form(), init_menu_files(), init_pick(), init_view_files(), lf_process(), locate_file_in_path(), menu_cmd_processor(), mk_dir(), open_curses(), output_objects(), parse_menu_description(), popup_ckeys(), search(), verify_spec_arg(), view_cmd_processor(), view_display_help(), view_init_input(), whence(), write_config(), and write_view_buffer().

Here is the caller graph for this function:

◆ strnz__cpy()

size_t strnz__cpy ( char * d,
const char * s,
size_t max_len )

safer alternative to strncpy

copies string s to d, ensuring that the total length of d does not exceed max_len, and that the resulting string is null-terminated. It also treats newline and carriage return characters as string terminators, preventing them from being included in the result. This is particularly useful when copying user input or file data, where embedded newlines could cause issues.

Parameters
d- destination string
s- source string
max_len- maximum length to copy
Returns
length of resulting string

Definition at line 269 of file futil.c.

269 {
270 char *e;
271 size_t len = 0;
272 if (s == nullptr || d == nullptr || max_len == 0) {
273 if (d != nullptr && max_len > 0)
274 *d = '\0';
275 return 0;
276 }
277 e = d + max_len;
278 while (*s != '\0' && *s != '\n' && *s != '\r' && d < e) {
279 *d++ = *s++;
280 len++;
281 }
282 *d = '\0';
283 return len;
284}

Referenced by answer_yn(), build_prompt(), canonicalize_file_spec(), derive_file_spec(), dir_name(), display_error(), display_pick_help(), display_prompt(), enter_file_spec(), exec_objects(), expand_tilde(), file_spec_parts(), form_desc_error(), form_display_screen(), form_engine(), form_exec_cmd(), form_fmt_field(), form_parse_desc(), form_process(), form_read_data(), form_write(), get_cmd_arg(), handle_signal(), init_form(), init_form_files(), init_menu_files(), init_pick(), init_pick_files(), init_view_boxwin(), init_view_files(), lf_process(), locate_file_in_path(), main(), mapp_initialization(), menu_cmd_processor(), mk_dir(), new_form(), open_curses(), output_objects(), parse_config(), parse_menu_description(), Perror(), popup_ckeys(), rep_substring(), save_object(), search(), verify_dir(), verify_file(), verify_spec_arg(), view_cmd_processor(), view_display_help(), view_file(), view_init_input(), whence(), write_config(), and write_view_buffer().

Here is the caller graph for this function:

◆ strnz_dup()

char * strnz_dup ( char * s,
size_t l )

Allocates memory for and duplicates string s up to length l or until line feed or carriage return.

Parameters
s- string to duplicate
l- maximum length to copy
Returns
pointer to allocated memory

Definition at line 379 of file futil.c.

379 {
380 char *p, *rs, *e;
381 size_t m;
382 if (s == nullptr || *s == '\0' || l == 0)
383 return nullptr;
384 for (p = s, m = 1; *p != '\0'; p++, m++)
385 ;
386 rs = p = (char *)malloc(m);
387 if (rs != nullptr) {
388 e = rs + l;
389 while (*s != '\0' && *s != '\n' && *s != '\r' && p < e)
390 *p++ = *s++;
391 *p = '\0';
392 }
393 return rs;
394}

Referenced by new_view().

Here is the caller graph for this function:

◆ strz()

size_t strz ( char * s)

Terminates string at new line or carriage return.

Parameters
sstring to terminate

Definition at line 322 of file futil.c.

322 {
323 size_t l = 0;
324 if (s == nullptr || *s == '\0')
325 return 0;
326 while (*s != '\0' && *s != '\n' && *s != '\r') {
327 s++;
328 l++;
329 }
330 *s = '\0';
331 return l;
332}

◆ trim()

size_t trim ( char * s)

Trims leading and trailing spaces from string s in place.

Parameters
s- string to trim
Returns
length of trimmed string

Definition at line 118 of file futil.c.

118 {
119 if (s == nullptr || *s == '\0')
120 return 0;
121 char *p = s;
122 char *d = s;
123 while (*p == ' ')
124 p++;
125 while (*p != '\0')
126 *d++ = *p++;
127 while (*(d - 1) == ' ' && d > s)
128 d--;
129 *d = '\0';
130 return (size_t)(d - s);
131}

Referenced by form_fmt_field(), form_parse_desc(), left_justify(), menu_cmd_processor(), parse_menu_description(), and right_justify().

Here is the caller graph for this function:

◆ trim_ext()

bool trim_ext ( char * buf,
char * filename )

trims the file extension from "filename" and copies the result to "buf"

Parameters
buf- buffer to receive result
filename- filename to trim
Note
The caller is responsible for ensuring that "buf" has enough space to receive the result.

Definition at line 741 of file futil.c.

742 {
743 if (!filename || !*filename || !buf)
744 return false;
745 char *s = filename;
746 char *d = buf;
747 *d = '\0';
748 while (*s)
749 s++;
750 while (filename < --s) {
751 if (*s == '.') {
752 break;
753 }
754 }
755 if (*s != '.') {
756 while (*filename)
757 *d++ = *filename++;
758 } else {
759 while (filename < s) {
760 *d++ = *filename++;
761 }
762 }
763 *d = '\0';
764 if (d == buf)
765 return false;
766 return true;

◆ trim_path()

bool trim_path ( char * dir)

Trims trailing spaces and slashes from directory path in place.

Parameters
dir- directory path to trim
Returns
true if successful

Definition at line 713 of file futil.c.

714 {
715 if (!dir)
716 return false;
717 char *p;
718
719 if (!dir || !*dir)
720 return false;
721 p = dir;
722 while (*p++ != '\0') {
723 if (*p == ' ' || *p == '\t' || *p == '\n') {
724 *p = '\0';
725 break;
726 }
727 }
728 --p;
729 while (--p > dir && *p == '/') {
730 if (*(p - 1) != '~')
731 *p = '\0';
732 }
733 return true;

Referenced by derive_file_spec().

Here is the caller graph for this function:

◆ verify_dir()

bool verify_dir ( char * spec,
int imode )

Verifies that the directory specified by "spec" exists and is accessible with the permissions specified by "imode".

Parameters
spec- directory specification
imode- access mode F_OK - existence R_OK - read W_OK - Write X_OK - Execute S_WCOK - Write or Create S_QUIET - Suppress Error Messages
Note
S_WCOK and S_QUIET are stripped before calling faccessat
Returns
true if successful

Definition at line 841 of file futil.c.

842 {
843 if (spec == nullptr || *spec == '\0')
844 return false;
845 expand_tilde(spec, MAXLEN);
846 struct stat sb;
847 errno = 0;
848 src_line = 0;
849 int mode = imode & ~(S_WCOK | S_QUIET);
850 if (faccessat(AT_FDCWD, spec, mode, AT_EACCESS) != 0) {
851 src_line = __LINE__ - 2;
852 src_name = __FILE__;
853 strnz__cpy(fn, "faccessat", MAXLEN - 1);
854 } else {
855 if (fstatat(AT_FDCWD, spec, &sb, 0) != 0) {
856 src_line = __LINE__ - 1;
857 src_name = __FILE__;
858 strnz__cpy(fn, "fstatat", MAXLEN - 1);
859 } else {
860 if ((sb.st_mode & S_IFMT) != S_IFDIR) {
861 src_line = __LINE__ - 1;
862 src_name = __FILE__;
863 strnz__cpy(fn, "verify_file", MAXLEN - 1);
864 strnz__cpy(em2, "Not a regular file.", MAXLEN - 1);
865 }
866 }
867 }
868 if (src_line != 0) {
869 if (!(mode & S_QUIET)) {
870 ssnprintf(em0, MAXLEN - 1, "%s failed in %s at line %d", fn,
872 strnz__cpy(em1, spec, MAXLEN - 1);
873 strnz__cpy(em3, "Check the file", MAXLEN - 1);
875 }
876 return false;
877 }
878 return true;
int src_line
Definition dwin.c:129
char * src_name
Definition dwin.c:130
char em3[MAXLEN]
Definition dwin.c:135

References display_error(), em0, em1, em2, em3, expand_tilde(), fn, src_line, src_name, ssnprintf(), and strnz__cpy().

Referenced by mapp_initialization(), mk_dir(), and verify_spec_arg().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ verify_file()

bool verify_file ( char * in_spec,
int imode )

Verifies that the file specified by "in_spec" exists and is accessible with the permissions specified by "imode".

Parameters
in_spec- directory specification
imode- access mode F_OK - existence R_OK - read W_OK - Write X_OK - Execute S_WCOK - Write or Create S_QUIET - Suppress Error Messages
Note
S_WCOK and S_QUIET are stripped before calling faccessat
Returns
true if successful

Definition at line 892 of file futil.c.

893 {
894 if (in_spec == nullptr || *in_spec == '\0')
895 return false;
896 struct stat sb;
897 char spec[MAXLEN];
898 strnz__cpy(spec, in_spec, MAXLEN - 1);
899 int mode = imode & ~(S_WCOK | S_QUIET);
900 errno = 0;
901 src_line = 0;
903 expand_tilde(spec, MAXLEN);
904 if ((faccessat(AT_FDCWD, spec, mode, AT_EACCESS)) != 0) {
905 src_line = __LINE__ - 1;
906 src_name = __FILE__;
907 strnz__cpy(fn, "faccessat", MAXLEN - 1);
908 } else {
909 if ((fstatat(AT_FDCWD, spec, &sb, 0)) != 0) {
910 src_line = __LINE__ - 1;
911 src_name = __FILE__;
912 strnz__cpy(fn, "fstatat", MAXLEN - 1);
913 } else {
914 if ((sb.st_mode & S_IFMT) != S_IFREG) {
915 src_line = __LINE__ - 1;
916 src_name = __FILE__;
917 strnz__cpy(fn, "verify_file", MAXLEN - 1);
918 strnz__cpy(em2, "Not a regular file.", MAXLEN - 1);
919 }
920 }
921 }
922 if (src_line != 0) {
923 if (imode & S_QUIET)
924 return false;
925 ssnprintf(em0, MAXLEN - 1, "%s failed in %s at line %d", fn, src_name,
926 src_line);
927 strnz__cpy(em1, spec, MAXLEN - 1);
928 strnz__cpy(em3, "Check the file", MAXLEN - 1);
930 return false;
931 }
932 return true;

References canonicalize_file_spec(), display_error(), em0, em1, em2, em3, expand_tilde(), fn, src_line, src_name, ssnprintf(), and strnz__cpy().

Referenced by verify_spec_arg().

Here is the call graph for this function:
Here is the caller graph for this function: