STASIS
A pipeline delivery generator
Loading...
Searching...
No Matches
utils.h File Reference
#include <stdio.h>
#include <stdlib.h>
#include <dirent.h>
#include <string.h>
#include <unistd.h>
#include <limits.h>
#include <errno.h>
#include "core.h"
#include "log.h"
#include "copy.h"
#include "system.h"
#include "strlist.h"
#include "utils.h"
#include "ini.h"
Include dependency graph for utils.h:

Go to the source code of this file.

Macros

#define PATH_ENV_VAR   "PATH"
#define DIR_SEP   "/"
#define PATH_SEP   ":"
#define LINE_SEP   "\n"
#define STASIS_RANDOM_GENERATOR_FILE   NULL
#define NEED_SRAND   1
#define STASIS_XML_PRETTY_PRINT_PROG   "xmllint"
#define STASIS_XML_PRETTY_PRINT_ARGS   "--format"
#define STASIS_COLOR_RED   "\x1b[1;91m"
 Set output color to red.
#define STASIS_COLOR_GREEN   "\x1b[1;92m"
 Set output color to green.
#define STASIS_COLOR_YELLOW   "\x1b[1;93m"
 Set output color to yellow.
#define STASIS_COLOR_BLUE   "\x1b[1;94m"
 Set output color to blue.
#define STASIS_COLOR_WHITE   "\x1b[1;97m"
 Set output color to white.
#define STASIS_COLOR_RESET   "\x1b[0;37m\x1b[0m"
 Reset output color to terminal default.
#define STASIS_MSG_SUCCESS   0
#define STASIS_MSG_NOP   1 << 0
 Suppress printing of the message text.
#define STASIS_MSG_ERROR   1 << 1
 The message is an error.
#define STASIS_MSG_WARN   1 << 2
 The message is a warning.
#define STASIS_MSG_L1   1 << 3
 The message will be indented once.
#define STASIS_MSG_L2   1 << 4
 The message will be indented twice.
#define STASIS_MSG_L3   1 << 5
 The message will be indented thrice.
#define STASIS_MSG_RESTRICT   1 << 6
 The message will only be printed in verbose mode.

Functions

int pushd (const char *path)
int popd (void)
char * expandpath (const char *_path)
int rmtree (char *_path)
char ** file_readlines (const char *filename, size_t start, size_t limit, ReaderFn *readerFn)
char * path_basename (char *path)
char * path_dirname (char *path)
char * find_program (const char *name)
int touch (const char *filename)
int git_clone (struct Process *proc, char *url, char *destdir, char *gitref)
char * git_describe (const char *path)
char * git_rev_parse (const char *path, char *args)
int is_git_assumed_unchanged (char *filename)
int path_store (char **destptr, size_t maxlen, const char *base, const char *path)
void msg (unsigned type, char *fmt,...)
void debug_shell ()
char * xmkstemp (FILE **fp, const char *mode)
int isempty_dir (const char *path)
int xml_pretty_print_in_place (const char *filename, const char *pretty_print_prog, const char *pretty_print_args)
int fix_tox_conf (const char *filename, char **result, size_t maxlen)
char * collapse_whitespace (char **s)
int redact_sensitive (const char **to_redact, size_t to_redact_size, char *src, char *dest, size_t maxlen)
struct StrListlistdir (const char *path)
long get_cpu_count ()
int mkdirs (const char *_path, mode_t mode)
int env_manipulate_pathstr (const char *key, char *path, int mode)
int gen_file_extension_str (char *filename, size_t maxlen, const char *extension)
char * remove_extras (char *s)
void debug_hexdump (char *data, size_t len)
int grow (size_t size_new, size_t *size_orig, char **data)
int in_ascii_range (char c, char lower, char upper)
int is_git_sha (char const *hash)
int check_python_package_dependencies (const char *srcdir, struct StrList **out_files, struct StrList **out_matches)
void seconds_to_human_readable (int v, char *result, size_t maxlen)
int str_to_timeout (char *s)
const char * get_random_generator_file ()
int get_random_bytes (char *result, size_t maxlen)
int non_format_len (const char *s)
char * center_text (const char *s, size_t maxwidth)
int is_file_compressed (const char *filename)

Function Documentation

◆ collapse_whitespace()

char * collapse_whitespace ( char ** s)

Collapse all whitespace in a string (to single spaces)

Parameters
saddress of string to modify
Returns

◆ env_manipulate_pathstr()

int env_manipulate_pathstr ( const char * key,
char * path,
int mode )

Return pointer to a (possible) version specifier

```c char s[] = "abc==1.2.3"; char *spec_begin = find_version_spec(s); // spec_begin is "==1.2.3"

char package_name[255]; char s[] = "abc"; char *spec_pos = find_version_spec(s); if (spec_pos) { strncpy(package_name, spec_pos - s); // use spec } else { // spec not found }

Parameters
stra pointer to a buffer containing a package spec (i.e. abc==1.2.3, abc>=1.2.3, abc)
Returns
a pointer to the first occurrence of a version spec character
NULL if not found */ char *find_version_spec(char *package_name);

mode flags for env_manipulate_pathstr #define PM_APPEND 1 << 0 #define PM_PREPEND 1 << 1 #define PM_ONCE 1 << 2

/** Add paths to the head or tail of an environment variable.

Parameters
keyenvironment variable to manipulate
pathto insert (does not need to exist)
modePM_APPEND $path:$PATH
modePM_PREPEND $PATH:path
modePM_ONCE do not manipulate if path is present in PATH variable
Here is the call graph for this function:

◆ expandpath()

char * expandpath ( const char * _path)

Expand "~" to the user's home directory

char *home = expandpath("~"); // == /home/username
char *config = expandpath("~/.config"); // == /home/username/.config
char *nope = expandpath("/tmp/test"); // == /tmp/test
char *nada = expandpath("/~/broken"); // == /~/broken
free(home);
free(config);
free(nope);
free(nada);
char * expandpath(const char *_path)
Definition utils.c:77
Parameters
_path(Must start with a ~)
Returns
success=expanded path or original path, failure=NULL
Here is the call graph for this function:

◆ find_program()

char * find_program ( const char * name)

Scan PATH directories for a named program

Parameters
nameprogram name
Returns
path to program, or NULL on error

◆ fix_tox_conf()

int fix_tox_conf ( const char * filename,
char ** result,
size_t maxlen )

Applies STASIS fixups to a tox ini config

Parameters
filenamepath to tox.ini
resultpath to processed configuration
maxlen
Returns
0 on success, -1 on error
Parameters
filename/path/to/tox.ini
resultpath of replacement tox.ini configuration
maxlen
Returns
0 on success, -1 on error
Here is the call graph for this function:

◆ gen_file_extension_str()

int gen_file_extension_str ( char * filename,
size_t maxlen,
const char * extension )

Append or replace a file extension

Here is the call graph for this function:

◆ get_cpu_count()

long get_cpu_count ( )

Get CPU count

Returns
CPU count on success, zero on error

◆ git_clone()

int git_clone ( struct Process * proc,
char * url,
char * destdir,
char * gitref )

Clone a git repository

struct Process proc;
memset(proc, 0, sizeof(proc));
if (git_clone(&proc, "https://github.com/myuser/myrepo", "./repos", "unstable_branch")) {
fprintf(stderr, "Failed to clone repository\n");
exit(1);
}
if (pushd("./repos/myrepo")) {
fprintf(stderr, "Unable to enter repository directory\n");
} else {
// do something with repository
popd();
}
Definition system.h:19
int git_clone(struct Process *proc, char *url, char *destdir, char *gitref)
Definition utils.c:309
int pushd(const char *path)
Definition utils.c:9
int popd(void)
Definition utils.c:24
See also
pushd
Parameters
procProcess struct
urlURL (or file system path) of repoistory to clone
destdirdestination directory
gitrefcommit/branch/tag of checkout (NULL will use HEAD of default branch for repo)
Returns
exit code from "git"
Here is the call graph for this function:

◆ git_describe()

char * git_describe ( const char * path)

Git describe wrapper

Parameters
pathto repository
Returns
output from "git describe", or NULL on error
Here is the call graph for this function:

◆ git_rev_parse()

char * git_rev_parse ( const char * path,
char * args )

Git rev-parse wrapper

Parameters
pathto repository
argsto pass to git rev-parse
Returns
output from "git rev-parse", or NULL on error
Here is the call graph for this function:

◆ grow()

int grow ( size_t size_new,
size_t * size_orig,
char ** data )

Realloc helper

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "utils.h"
int main(int argc, char *argv[]) {
size_t sz = 10;
char *data = calloc(sz, sizeof(*data));
// populate data
strncat(data, "/path/to/", sz - 1);
// Double the allocation size for data
if (grow(sz * 2, &sz, &data)) {
// memory error
}
// sz is now 20
strncat(data, "filename", sz - 1 - strlen(data));
puts(data);
// output: "/path/to/filename"
}
int grow(size_t size_new, size_t *size_orig, char **data)
Definition utils.c:988
Parameters
size_newincrease by size_new bytes
size_origaddress of variable containing the original allocation size (modified)
dataaddress to write data
Returns
0 on success
-1 on error

◆ is_file_compressed()

int is_file_compressed ( const char * filename)

Check magic bytes against known compression formats

const char *filename = "/path/to/file.zip";
if (is_file_compressed(filename)) {
// file is compressed
} else {
// file is not compressed
}
int is_file_compressed(const char *filename)
Definition utils.c:1274
Parameters
filenamepath to maybe-compressed file
Returns
0 if not compressed
1 if compressed

◆ is_git_assumed_unchanged()

int is_git_assumed_unchanged ( char * filename)

Check if a file in a git repository is flagged with 'assumed-unchanged'.

Parameters
filenamepath to file
Returns
-1 on error, 0 if

Check if a file in a git repository is flagged as 'assumed-unchanged'.

Parameters
filenamepath to file
Returns
-1 on error, 0 if
Here is the call graph for this function:

◆ isempty_dir()

int isempty_dir ( const char * path)

Is the path an empty directory structure?

if (isempty_dir("/some/path")) {
fprintf(stderr, "The directory is is empty!\n");
} else {
printf("The directory contains dirs/files\n");
}
int isempty_dir(const char *path)
Definition utils.c:539
Parameters
pathdirectory
Returns
0 = no, 1 = yes

◆ listdir()

struct StrList * listdir ( const char * path)

Given a directory path, return a list of files

struct StrList *files;
basepath = ".";
files = listdir(basepath);
for (size_t i = 0; i < strlist_count(files); i++) {
char *filename = strlist_item(files, i);
printf("%s/%s\n", basepath, filename);
}
guard_strlist_free(&files);
char * strlist_item(struct StrList *pStrList, size_t index)
Definition strlist.c:488
size_t strlist_count(struct StrList *pStrList)
Definition strlist.c:419
Definition strlist.h:16
struct StrList * listdir(const char *path)
Definition utils.c:829
Parameters
pathof a directory
Returns
a StrList containing file names

Retrieve file names in a directory (no metadata, non-recursive)

Parameters
pathdirectory path
Returns
StrList structure
Here is the call graph for this function:

◆ mkdirs()

int mkdirs ( const char * _path,
mode_t mode )

Create all leafs in directory path

Parameters
_pathdirectory path to create
modemode_t permissions
Returns

◆ non_format_len()

int non_format_len ( const char * s)

Get length of s as if any formatters are not present

Parameters
sformat string
Returns
length

◆ path_basename()

char * path_basename ( char * path)

Strip directory from file name Note: Caller is responsible for freeing memory

Parameters
_path
Returns
success=file name, failure=NULL

◆ path_dirname()

char * path_dirname ( char * path)

Return parent directory of file, or the parent of a directory

Parameters
path
Returns
success=directory, failure=empty string

◆ path_store()

int path_store ( char ** destptr,
size_t maxlen,
const char * base,
const char * path )

Helper function to initialize simple STASIS internal path strings

char *mypath = NULL;
if (path_store(&mypath, PATH_MAX, "/some", "path")) {
fprintf(stderr, "Unable to allocate memory for path elements\n");
exit(1);
}
// mypath is allocated to size PATH_MAX and contains the string: /some/path
// base+path will truncate at maxlen - 1
int path_store(char **destptr, size_t maxlen, const char *base, const char *path)
Definition utils.c:557
Parameters
destptraddress of destination string pointer
maxlenmaximum length of the path
basepath
pathto append to base
Returns
0 on success, -1 on error
Here is the call graph for this function:

◆ popd()

int popd ( void )

Return from directory. Pop last path from directory stack.

See also
pushd
Returns
0 on success, -1 if stack is empty

◆ pushd()

int pushd ( const char * path)

Change directory. Push path on directory stack.

pushd("/somepath");
FILE fp = fopen("somefile", "w"); // i.e. /somepath/somefile
fprintf(fp, "Hello world.\n");
fclose(fp);
popd();
Parameters
pathof directory
Returns
0 on success, -1 on error
Here is the call graph for this function:

◆ redact_sensitive()

int redact_sensitive ( const char ** to_redact,
size_t to_redact_size,
char * src,
char * dest,
size_t maxlen )

Write REDACTED in dest for each occurrence of to_redacted token present in src

char command[PATH_MAX] = {0};
char command_redacted[PATH_MAX] = {0};
const char *password = "abc123";
const char *host = "myhostname";
const char *to_redact_case1[] = {password, host, NULL};
const char *to_redact_case2[] = {password, "--host", NULL};
const char *to_redact_case3[] = {password, "--host", host, NULL};
sprintf(command, "echo %s | program --host=%s -", password, host);
// CASE 1
redact_sensitive(to_redact_case1, command, command_redacted, sizeof(command_redacted) - 1);
printf("executing: %s\n", command_redacted);
// User sees:
// executing: echo ***REDACTED*** | program --host=***REDACTED*** -
system(command);
// CASE 2 remove an entire argument
redact_sensitive(to_redact_case2, command, command_redacted, sizeof(command_redacted) - 1);
printf("executing: %s\n", command_redacted);
// User sees:
// executing: echo ***REDACTED*** | program ***REDACTED*** -
system(command);
// CASE 3 remove it all (noisy)
redact_sensitive(to_redact_case3, command, command_redacted, sizeof(command_redacted) - 1);
printf("executing: %s\n", command_redacted);
// User sees:
// executing: echo ***REDACTED*** | program ***REDACTED***=***REDACTED*** -
system(command);
int redact_sensitive(const char **to_redact, size_t to_redact_size, char *src, char *dest, size_t maxlen)
Definition utils.c:799
Parameters
to_redactarray of tokens to redact
srcinput string
destoutput string
maxlenmaximum length of dest byte array
Returns
0 on success, -1 on error

Replace sensitive text in strings with REDACTED

Parameters
to_redacta list of tokens to redact
to_redact_sizelimit to n tokens in list
srcto read
destto write modified string
maxlenmaximum length of dest string
Returns
0 on success, -1 on error
Here is the call graph for this function:

◆ remove_extras()

char * remove_extras ( char * s)

Remove [extra]s from a spec string

◆ rmtree()

int rmtree ( char * _path)

Remove a directory tree recursively

mkdirs("a/b/c");
rmtree("a");
// a/b/c is removed
int rmtree(char *_path)
Definition utils.c:35
int mkdirs(const char *_path, mode_t mode)
Definition utils.c:866
Parameters
_path
Returns
0 on success, -1 on error
Here is the call graph for this function:

◆ touch()

int touch ( const char * filename)

Create an empty file, or update modified timestamp on an existing file

Parameters
filenamefile to touch
Returns
0 on success, 1 on error

◆ xmkstemp()

char * xmkstemp ( FILE ** fp,
const char * mode )

Creates a temporary file returning an open file pointer via fp, and the path to the file. The caller is responsible for closing fp and free()ing the returned file path.

FILE *fp = NULL;
char *tempfile = xmkstemp(&fp, "r+");
if (!fp || !tempfile) {
fprintf(stderr, "Failed to generate temporary file for read/write\n");
exit(1);
}
char * xmkstemp(FILE **fp, const char *mode)
Definition utils.c:501
Parameters
fppointer to FILE (to be initialized)
modefopen() style file mode string
Returns
system path to the temporary file
NULL on failure
Here is the call graph for this function:

◆ xml_pretty_print_in_place()

int xml_pretty_print_in_place ( const char * filename,
const char * pretty_print_prog,
const char * pretty_print_args )

Rewrite an XML file with a pretty printer command

Parameters
filenamepath to modify
pretty_print_progprogram to call
pretty_print_argsarguments to pass to program
Returns
0 on success, -1 on error
Here is the call graph for this function: