C-Menu 0.2.9
A User Interface Toolkit
Loading...
Searching...
No Matches
futil.c File Reference

General utility functions. More...

#include "cm.h"
#include <argp.h>
#include <arpa/inet.h>
#include <ctype.h>
#include <dirent.h>
#include <errno.h>
#include <fcntl.h>
#include <grp.h>
#include <ifaddrs.h>
#include <pthread.h>
#include <pwd.h>
#include <regex.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <termios.h>
#include <time.h>
#include <unistd.h>
#include <wait.h>
Include dependency graph for futil.c:

Go to the source code of this file.

Macros

#define LF_DIR   2
#define LF_LNK   1
#define LF_REG   4

Functions

unsigned long a_to_ul (const char *str)
 Converts a string to an unsigned long long integer, with support for suffixes K, M, and G for kilobytes, megabytes, and gigabytes respectively.
int a_toi (char *s, bool *a_toi_error)
 a safer alternative to atoi() for converting ASCII strings to integers.
bool base_name (char *buf, char *path)
 Returns the base name of a file specification.
size_t canonicalize_file_spec (char *spec)
 Removes quotes and trims at first space.
bool chrep (char *s, char old_chr, char new_chr)
 Replaces all occurrences of old_chr in s with new_chr in place.
int destroy_argv (uint argc, char **argv)
 Deallocates memory allocated for argument strings in argv.
bool dir_name (char *buf, char *path)
 Returns the directory name of a file specification.
bool expand_tilde (char *str, uint path_maxlen)
 Replaces "~/" in string with the user's home directory.
char * fdname (int fd, char *out_path)
 Retrieves the file path associated with a given file descriptor.
bool file_spec_name (char *file_name, char *fs)
 extracts the file name component of a file specification
bool file_spec_path (char *fp, char *fs)
 extracts the path component of a file specification
FileType file_type (const char *filename)
char * fill_field (char *accept_s, char *display_s, char fill_char, uint flen)
char * format_local_timestamp (time_t t, char *buf, size_t n)
 Formats a time_t as an ISO 8601 string in local time.
String free_string (String string)
 Free the dynamically allocated String.
bool get_argp_doc_by_name (char *comment, const struct argp_option *options, const char *key_name)
 Retrieves the documentation string for a given key name from an argp options array.
char * get_ip_addresses (char *ip_str, uint maxlen)
 Retrieves the IP addresses of the local machine and formats them into a string.
char * get_local_timestamp ()
 Returns the current local time as an ISO 8601 formatted string.
char * get_user_str (char *user_str, size_t maxlen)
 Retrieves the current user's name and UID, and formats it into a string.
bool is_directory (const char *path)
 Checks if the given path is a directory.
bool is_hex_str (char *str, uint len)
 Validates that a string consists of exactly len hexadecimal digits.
bool is_newer (char *control, char *fut)
 Checks if the file specified by "fut" is newer than the file specified by "control".
bool is_symlink_to_dir (const char *path)
 Checks if the given path is a symbolic link to a directory.
bool is_valid_date (uint yyyy, uint mm, uint dd)
 Check if a given date is valid, including leap years.
bool is_valid_regex (const char *pattern)
 Checks if the given regular expression pattern is valid.
bool is_valid_time (uint hh, uint mm, uint ss)
 Check if a given time is valid.
void left_justify (char *s)
 Left justify string by removing leading spaces.
bool locate_file_in_path (char *file_spec, char *file_name)
 Locates a file in the system PATH.
bool mk_dir (char *dir)
 If directory doesn't exist, make it.
String mk_string (size_t l)
 Create a String struct with a dynamically allocated string.
bool normalize_file_spec (char *fs)
 replace backslashes with forward lashes
void numeric (char *d, char *s)
 Extract numeric characters from source string to destination string.
bool parse_local_timestamp (const char *s, time_t *out)
 Parses an ISO 8601 timestamp string in local time and converts it to time_t.
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".
void right_justify (char *s, uint fl)
 Right justify string by removing trailing spaces and adding leadingspaces.
size_t rtrim (char *s)
 Trims trailing spaces from string s in place.
int segmentation_fault ()
 Function to intentionally cause a segmentation fault for testing purposes.
size_t ssnprintf (char *buf, size_t buf_size, const char *format,...)
 ssnprintf was designed to be a safer alternative to snprintf.
char * stdio_fdnames (char *stdio_str, char *id)
char * stdio_names (char *stdio_str, char *id)
bool str_subc (char *d, char *s, char ReplaceChr, char *Withstr, uint 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.
int str_to_args (char **argv, char *arg_str, uint max_args)
 Converts a string into an array of argument strings.
bool str_to_bool (const char *s)
 Converts String to boolean true or false.
double str_to_double (char *s)
 converts string to double
bool str_to_lower (char *s)
 Converts a string to lowercase.
bool str_to_upper (char *s)
 Converts a string to uppercase.
char * strerror__r (int errnum, char *buf, size_t buflen)
 A thread-safe alternative to strerror() that writes the error message corresponding to errnum into the provided buffer.
size_t string_cat (String *dest, const String *src)
 Concatenates src String to dest String, allocating additional memory for dest String if necessary.
size_t string_cpy (String *dest, const String *src)
 Copy src String to dest String, allocating additional memory for dest String if necessary.
size_t string_ncat (String *dest, const String *src, size_t n)
 Concatenates up to n characters from src String to dest String, allocating additional memory for dest String if necessary.
size_t string_ncpy (String *dest, const String *src, size_t n)
 copies up to n characters from src String to dest String, allocating additional memory for dest String if necessary
size_t strip_ansi (char *d, char *s)
 Strips ANSI SGR escape sequences (ending in 'm') from string s to d.
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
size_t strnlf (char *s, size_t max_len)
 terminates string with line feed
size_t strnz (char *s, size_t max_len)
 terminates string at New Line, Carriage Return, or max_len
size_t strnz__cat (char *d, const char *s, size_t max_len)
 safer alternative to strncat
size_t strnz__cpy (char *d, const char *s, size_t max_len)
 safer alternative to strncpy
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.
size_t strz (char *s)
 Terminates string at new line or carriage return.
String to_string (const char *s)
 String functions provide a simple string library to facilitate string manipulation in C, allowing developers to easily create, copy, concatenate, and free strings without having to manage memory manually.
size_t trim (char *s)
 Trims leading and trailing spaces from string s in place.
bool trim_ext (char *buf, char *filename)
 trims the file extension from "filename" and copies the result to "buf"
bool trim_path (char *dir)
 Trims trailing spaces and slashes from directory path in place.
bool unstr_hex_clr (char *dst, char *str)
 Validates that a string is a hex color code in the format "#RRGGBB".
bool verify_dir (char *spec, uint imode)
 Verifies that the directory specified by "spec" exists and is accessible with the permissions specified by "imode".
bool verify_file (char *in_spec, uint imode)
 Verifies that the file specified by "in_spec" exists and is accessible with the permissions specified by "imode".

Variables

int cmenu_log_fd
char earg_str [MAXLEN]
int eargc
char * eargv [MAXARGS]
char errmsg [MAXLEN]
error_info_t error_info
error_source_t error_source
char stdio_names_str [4096]
int wait_timeout

Detailed Description

General utility functions.

Author
Bill Waller Copyright (c) 2025 MIT License billx.nosp@m.wall.nosp@m.er@gm.nosp@m.ail..nosp@m.com
Date
2026-02-09

Definition in file futil.c.

Macro Definition Documentation

◆ LF_DIR

#define LF_DIR   2

Definition at line 44 of file futil.c.

◆ LF_LNK

#define LF_LNK   1

Definition at line 43 of file futil.c.

◆ LF_REG

#define LF_REG   4

Definition at line 45 of file futil.c.

Function Documentation

◆ file_type()

FileType file_type ( const char * filename)

Definition at line 1726 of file futil.c.

1727 {
1728 FILE *file = fopen(filename, "rb");
1729 if (!file) {
1730 return FT_UNREADABLE;
1731 }
1732 unsigned char buffer[1024];
1733 size_t bytes_read = fread(buffer, 1, sizeof(buffer), file);
1734 fclose(file);
1735 if (bytes_read == 0) {
1736 return FT_EMPTY;
1737 }
1738 // --- IMAGE MAGIC BYTES ---
1739 if (bytes_read >= 3 && buffer[0] == 0xFF && buffer[1] == 0xD8 && buffer[2] == 0xFF) {
1740 return FT_IMAGE; // JPEG
1741 }
1742 if (bytes_read >= 8 && buffer[0] == 0x89 && buffer[1] == 0x50 && buffer[2] == 0x4E && buffer[3] == 0x47 &&
1743 buffer[4] == 0x0D && buffer[5] == 0x0A && buffer[6] == 0x1A && buffer[7] == 0x0A) {
1744 return FT_IMAGE; // PNG
1745 }
1746 if (bytes_read >= 4 && buffer[0] == 'G' && buffer[1] == 'I' && buffer[2] == 'F' && buffer[3] == '8') {
1747 return FT_IMAGE; // GIF
1748 }
1749 if (bytes_read >= 12 && buffer[0] == 'R' && buffer[1] == 'I' && buffer[2] == 'F' && buffer[3] == 'F' &&
1750 buffer[8] == 'W' && buffer[9] == 'E' && buffer[10] == 'B' && buffer[11] == 'P') {
1751 return FT_IMAGE; // WebP
1752 }
1753 // --- STEP 2: HEURISTIC CHECK FOR BINARY GARBAGE ---
1754 size_t control_chars = 0;
1755 for (size_t i = 0; i < bytes_read; i++) {
1756 unsigned char c = buffer[i];
1757 // Immediate giveaway: true text files should never contain null
1758 // characters
1759 if (c == 0x00) {
1760 return FT_BINARY_GARBAGE;
1761 }
1762 // Count non-printable control characters
1763 // Skip common whitespace: tab (9), newline (10), carriage return (13)
1764 if (c < 32 && c != 9 && c != 10 && c != 13) {
1765 control_chars++;
1766 }
1767 }
1768 // If more than 10% of the sample block consists of raw control characters,
1769 // it's almost certainly a compiled binary or compressed archive.
1770 if ((double)control_chars / bytes_read > 0.10) {
1771 return FT_BINARY_GARBAGE;
1772 }
1773 return FT_TEXT;

◆ fill_field()

char * fill_field ( char * accept_s,
char * display_s,
char fill_char,
uint flen )

Definition at line 1714 of file futil.c.

1715 {
1716 char *s = accept_s;
1717 char *d = display_s;
1718 char *e = d + flen;
1719 while (*s != '\0' && d < e)
1720 *d++ = *s++;
1721 while (d < e)
1722 *d++ = fill_char;
1723 *d = '\0';
1724 return display_s;

◆ mk_string()

String mk_string ( size_t l)

Create a String struct with a dynamically allocated string.

Parameters
llength of string to create including null terminator
Returns
String struct

The returned String struct contains a dynamically allocated string of he specified length

Note
the caller is responsible for calling free_string to free the allocated memory.

Definition at line 1550 of file futil.c.

1551 {
1552 if (l == 0) {
1553 String str;
1554 str.l = 0;
1555 str.s = nullptr;
1556 return str;
1557 }
1558 String str;
1559 str.l = l + 1;
1560 str.s = (char *)malloc(str.l);
1561 str.s[0] = '\0';
1562 return str;
Definition cm.h:409
size_t l
Definition cm.h:411
char * s
Definition cm.h:410

References String::l, and String::s.

◆ rtrim()

size_t rtrim ( char * s)

Trims trailing spaces from string s in place.

Parameters
s- string to trim
Returns
length of trimmed string

Definition at line 308 of file futil.c.

308 {
309 if (s == nullptr || *s == '\0')
310 return (size_t)0;
311 char *p = s + strlen(s) - 1;
312 while (p >= s && *p == ' ')
313 p--;
314 *(p + 1) = '\0';
315 return (size_t)(p - s + 1);
316}

Referenced by fmt_line(), and picker().

Here is the caller graph for this function:

◆ stdio_fdnames()

char * stdio_fdnames ( char * stdio_str,
char * id )

Definition at line 1108 of file futil.c.

1109 {
1110 if (!stdio_str)
1111 return nullptr;
1112 char buf[MAXLEN] = {'\0'};
1113 char buf0[MAXLEN] = {'\0'};
1114 ssnprintf(buf, MAXLEN - 1, "%s: ", id);
1115 strnz__cpy(stdio_str, buf, MAXLEN - 1);
1116 for (int i = 0; i < 16; i++) {
1117 if (fdname(i, buf0) != nullptr) {
1118 ssnprintf(buf, 4095, " fd%d=%s", i, buf0);
1119 strnz__cat(stdio_str, buf, MAXLEN - 1);
1120 strnz__cat(stdio_str, ",", MAXLEN - 1);
1121 }
1122 }
1123 return stdio_str;
#define MAXLEN
Definition curskeys.c:15
size_t strnz__cpy(char *d, const char *s, size_t max_len)
safer alternative to strncpy
Definition futil.c:518
size_t ssnprintf(char *, size_t, const char *,...)
ssnprintf was designed to be a safer alternative to snprintf.
Definition futil.c:390
size_t strnz__cat(char *d, const char *s, size_t max_len)
safer alternative to strncat
Definition futil.c:549
char * fdname(int fd, char *out_path)
Retrieves the file path associated with a given file descriptor.
Definition futil.c:1073

References fdname(), ssnprintf(), strnz__cat(), and strnz__cpy().

Referenced by form_process(), init_pick(), and view_init_input().

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

◆ stdio_names()

char * stdio_names ( char * stdio_str,
char * id )

Definition at line 1083 of file futil.c.

1084 {
1085 if (!stdio_str)
1086 return nullptr;
1087 char buf[MAXLEN] = {'\0'};
1088 char err_str[MAXLEN] = {'\0'};
1089 errno = 0;
1090 ssnprintf(buf, MAXLEN - 1, "%s - ", id);
1091 strnz__cpy(stdio_str, buf, MAXLEN - 1);
1092 strnz__cat(stdio_str, ttyname(0), MAXLEN - 1);
1093 strnz__cat(stdio_str, ", ", MAXLEN - 1);
1094 if (errno)
1095 ssnprintf(err_str, MAXLEN - 1, "Error fd %d: %s\n", 0, strerror(errno));
1096
1097 strnz__cat(stdio_str, ttyname(1), MAXLEN - 1);
1098 strnz__cat(stdio_str, ", ", MAXLEN - 1);
1099 if (errno)
1100 ssnprintf(err_str, MAXLEN - 1, _("Error fd %d: %s\n"), 1, strerror(errno));
1101
1102 strnz__cat(stdio_str, ttyname(2), MAXLEN - 1);
1103 strnz__cat(stdio_str, ", ", MAXLEN - 1);
1104 if (errno)
1105 ssnprintf(err_str, MAXLEN - 1, _("Error fd %d: %s\n"), 2, strerror(errno));
1106
1107 return stdio_str;
#define _(String)
Definition amort.c:23

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

Referenced by fork_exec(), and menu_cmd_processor().

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

◆ str_to_bool()

bool str_to_bool ( const char * s)

Converts String to boolean true or false.

Parameters
s- string to convert
Returns
boolean true or false

Definition at line 960 of file futil.c.

961 {
962 if (s == nullptr || *s == '\0')
963 return false;
964 switch (s[0]) {
965 case 't':
966 case 'T':
967 case 'y':
968 case 'Y':
969 case '1':
970 return true;
971 case 'o':
972 case 'O':
973 switch (s[1]) {
974 case 'n':
975 case 'N':
976 return true;
977 default:
978 break;
979 }
980 default:
981 break;
982 }
983 return false;

Referenced by process_config_file().

Here is the caller graph for this function:

Variable Documentation

◆ cmenu_log_fd

int cmenu_log_fd

Definition at line 47 of file futil.c.

◆ earg_str

char earg_str

Definition at line 49 of file futil.c.

◆ eargc

int eargc

Definition at line 50 of file futil.c.

◆ eargv

char * eargv

Definition at line 51 of file futil.c.

◆ errmsg

char errmsg[MAXLEN]

Global variables for error reporting

Definition at line 126 of file futil.c.

◆ error_info

error_info_t error_info

Definition at line 138 of file futil.c.

◆ error_source

error_source_t error_source

Definition at line 139 of file futil.c.

◆ stdio_names_str

char stdio_names_str[4096]

Definition at line 122 of file futil.c.

Referenced by fork_exec(), form_process(), init_pick(), menu_cmd_processor(), and view_init_input().

◆ wait_timeout

int wait_timeout

Definition at line 140 of file futil.c.