/* * Shell-like utility functions * * Copyright (C) 2013, Broadcom Corporation. All Rights Reserved. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * * $Id: shutils.h 341899 2012-06-29 04:06:38Z $ */ #ifndef _shutils_h_ #define _shutils_h_ /* * Reads file and returns contents * @param fd file descriptor * @return contents of file or NULL if an error occurred */ extern char * fd2str(int fd); /* * Reads file and returns contents * @param path path to file * @return contents of file or NULL if an error occurred */ extern char * file2str(const char *path); /* * Waits for a file descriptor to become available for reading or unblocked signal * @param fd file descriptor * @param timeout seconds to wait before timing out or 0 for no timeout * @return 1 if descriptor changed status or 0 if timed out or -1 on error */ extern int waitfor(int fd, int timeout); #if defined(linux) || defined(__NetBSD__) /* * Concatenates NULL-terminated list of arguments into a single * commmand and executes it * @param argv argument list * @param path NULL, ">output", or ">>output" * @param timeout seconds to wait before timing out or 0 for no timeout * @param ppid NULL to wait for child termination or pointer to pid * @return return value of executed command or errno */ extern int _eval(char *const argv[], char *path, int timeout, pid_t *ppid); #endif /* defined(linux) */ /* * Concatenates NULL-terminated list of arguments into a single * commmand and executes it * @param argv argument list * @return stdout of executed command or NULL if an error occurred */ extern char * _backtick(char *const argv[]); /* * Kills process whose PID is stored in plaintext in pidfile * @param pidfile PID file * @return 0 on success and errno on failure */ extern int kill_pidfile(char *pidfile); #if defined(linux) /* * Returns the process ID. * * @param name pathname used to start the process. Do not include the * arguments. * @return pid */ extern pid_t get_pid_by_name(char *name); /* * fread() with automatic retry on syscall interrupt * @param ptr location to store to * @param size size of each element of data * @param nmemb number of elements * @param stream file stream * @return number of items successfully read */ extern int safe_fread(void *ptr, size_t size, size_t nmemb, FILE *stream); /* * fwrite() with automatic retry on syscall interrupt * @param ptr location to read from * @param size size of each element of data * @param nmemb number of elements * @param stream file stream * @return number of items successfully written */ extern int safe_fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream); #endif /* defined(linux) */ /* * Convert Ethernet address string representation to binary data * @param a string in xx:xx:xx:xx:xx:xx notation * @param e binary data * @return TRUE if conversion was successful and FALSE otherwise */ extern int ether_atoe(const char *a, unsigned char *e); /* * Convert Ethernet address binary data to string representation * @param e binary data * @param a string in xx:xx:xx:xx:xx:xx notation * @return a */ extern char * ether_etoa(const unsigned char *e, char *a); /* * Concatenate two strings together into a caller supplied buffer * @param s1 first string * @param s2 second string * @param buf buffer large enough to hold both strings * @return buf */ static inline char * strcat_r(const char *s1, const char *s2, char *buf) { strcpy(buf, s1); strcat(buf, s2); return buf; } /* * Parse the unit and subunit from an interface string such as wlXX or wlXX.YY * * @param ifname interface string to parse * @param unit pointer to return the unit number, may pass NULL * @param subunit pointer to return the subunit number, may pass NULL * @return Returns 0 if the string ends with digits or digits.digits, -1 otherwise. * If ifname ends in digits.digits, then unit and subuint are set * to the first and second values respectively. If ifname ends * in just digits, unit is set to the value, and subunit is set * to -1. On error both unit and subunit are -1. NULL may be passed * for unit and/or subuint to ignore the value. */ extern int get_ifname_unit(const char* ifname, int *unit, int *subunit); /* * Get interfaces belonging to a specific bridge. * * @param bridge_name pointer to bridge interface name * @return list on interfaces beloging to the bridge */ extern char * get_bridged_interfaces(char *bridge_name); /* remove_from_list Remove the specified word from the list. @param name word to be removed from the list @param list List to modify @param listsize Max size the list can occupy @return error code */ extern int remove_from_list(const char *name, char *list, int listsize); /* add_to_list Add the specified interface(string) to the list as long as it will fit in the space left in the list. @param name Name of interface to be added to the list @param list List to modify @param listsize Max size the list can occupy @return error code */ extern int add_to_list(const char *name, char *list, int listsize); extern char *find_in_list(const char *haystack, const char *needle); extern int nvifname_to_osifname(const char *nvifname, char *osifname_buf, int osifname_buf_len); extern int osifname_to_nvifname(const char *osifname, char *nvifname_buf, int nvifname_buf_len); extern char *remove_dups(char *inlist, int inlist_size); int ure_any_enabled(void); #if !defined(__NetBSD__) && !defined(__ARM_ARCH_7A__) /* Check for a blank character; that is, a space or a tab */ #define isblank(c) ((c) == ' ' || (c) == '\t') #endif /* Strip trailing CR/NL from string */ #define chomp(s) ({ \ char *c = (s) + strlen((s)) - 1; \ while ((c > (s)) && (*c == '\n' || *c == '\r')) \ *c-- = '\0'; \ s; \ }) /* Simple version of _backtick() */ #define backtick(cmd, args...) ({ \ char *argv[] = { cmd , ## args, NULL }; \ _backtick(argv); \ }) /* Simple version of _eval() (no timeout and wait for child termination) */ #define eval(cmd, args...) ({ \ char *argv[] = { cmd , ## args, NULL }; \ _eval(argv, ">/dev/console", 0, NULL); \ }) /* Copy each token in wordlist delimited by space into word */ #define foreach(word, wordlist, next) \ for (next = &wordlist[strspn(wordlist, " ")], \ strncpy(word, next, sizeof(word)), \ word[strcspn(word, " ")] = '\0', \ word[sizeof(word) - 1] = '\0', \ next = strchr(next, ' '); \ strlen(word); \ next = next ? &next[strspn(next, " ")] : "", \ strncpy(word, next, sizeof(word)), \ word[strcspn(word, " ")] = '\0', \ word[sizeof(word) - 1] = '\0', \ next = strchr(next, ' ')) /* Return NUL instead of NULL if undefined */ #define safe_getenv(s) (getenv(s) ? : "") #if defined(linux) || defined(__NetBSD__) /* Print directly to the console */ #define cprintf(fmt, args...) do { \ FILE *fp = fopen("/dev/console", "w"); \ if (fp) { \ fprintf(fp, fmt , ## args); \ fclose(fp); \ } \ } while (0) #endif /* Debug print */ #ifdef DEBUG #define dprintf(fmt, args...) cprintf("%s: " fmt, __FUNCTION__ , ## args) #else #define dprintf(fmt, args...) #endif /* DEBUG */ #ifdef __ECOS char * strsep(char **stringp, const char *delim); #endif /* __ECOS */ #endif /* _shutils_h_ */