1/* 2 * Shell-like utility functions 3 * 4 * Copyright (C) 2013, Broadcom Corporation. All Rights Reserved. 5 * 6 * Permission to use, copy, modify, and/or distribute this software for any 7 * purpose with or without fee is hereby granted, provided that the above 8 * copyright notice and this permission notice appear in all copies. 9 * 10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY 13 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION 15 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN 16 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 17 * 18 * $Id: shutils.h 341899 2012-06-29 04:06:38Z $ 19 */ 20 21#ifndef _shutils_h_ 22#define _shutils_h_ 23 24/* 25 * Reads file and returns contents 26 * @param fd file descriptor 27 * @return contents of file or NULL if an error occurred 28 */ 29extern char * fd2str(int fd); 30 31/* 32 * Reads file and returns contents 33 * @param path path to file 34 * @return contents of file or NULL if an error occurred 35 */ 36extern char * file2str(const char *path); 37 38/* 39 * Waits for a file descriptor to become available for reading or unblocked signal 40 * @param fd file descriptor 41 * @param timeout seconds to wait before timing out or 0 for no timeout 42 * @return 1 if descriptor changed status or 0 if timed out or -1 on error 43 */ 44extern int waitfor(int fd, int timeout); 45 46#if defined(linux) || defined(__NetBSD__) 47/* 48 * Concatenates NULL-terminated list of arguments into a single 49 * commmand and executes it 50 * @param argv argument list 51 * @param path NULL, ">output", or ">>output" 52 * @param timeout seconds to wait before timing out or 0 for no timeout 53 * @param ppid NULL to wait for child termination or pointer to pid 54 * @return return value of executed command or errno 55 */ 56extern int _eval(char *const argv[], char *path, int timeout, pid_t *ppid); 57#endif /* defined(linux) */ 58 59/* 60 * Concatenates NULL-terminated list of arguments into a single 61 * commmand and executes it 62 * @param argv argument list 63 * @return stdout of executed command or NULL if an error occurred 64 */ 65extern char * _backtick(char *const argv[]); 66 67/* 68 * Kills process whose PID is stored in plaintext in pidfile 69 * @param pidfile PID file 70 * @return 0 on success and errno on failure 71 */ 72extern int kill_pidfile(char *pidfile); 73 74#if defined(linux) 75/* 76 * Returns the process ID. 77 * 78 * @param name pathname used to start the process. Do not include the 79 * arguments. 80 * @return pid 81 */ 82extern pid_t get_pid_by_name(char *name); 83 84/* 85 * fread() with automatic retry on syscall interrupt 86 * @param ptr location to store to 87 * @param size size of each element of data 88 * @param nmemb number of elements 89 * @param stream file stream 90 * @return number of items successfully read 91 */ 92extern int safe_fread(void *ptr, size_t size, size_t nmemb, FILE *stream); 93 94/* 95 * fwrite() with automatic retry on syscall interrupt 96 * @param ptr location to read from 97 * @param size size of each element of data 98 * @param nmemb number of elements 99 * @param stream file stream 100 * @return number of items successfully written 101 */ 102extern int safe_fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream); 103#endif /* defined(linux) */ 104 105/* 106 * Convert Ethernet address string representation to binary data 107 * @param a string in xx:xx:xx:xx:xx:xx notation 108 * @param e binary data 109 * @return TRUE if conversion was successful and FALSE otherwise 110 */ 111extern int ether_atoe(const char *a, unsigned char *e); 112 113/* 114 * Convert Ethernet address binary data to string representation 115 * @param e binary data 116 * @param a string in xx:xx:xx:xx:xx:xx notation 117 * @return a 118 */ 119extern char * ether_etoa(const unsigned char *e, char *a); 120 121/* 122 * Concatenate two strings together into a caller supplied buffer 123 * @param s1 first string 124 * @param s2 second string 125 * @param buf buffer large enough to hold both strings 126 * @return buf 127 */ 128static inline char * strcat_r(const char *s1, const char *s2, char *buf) 129{ 130 strcpy(buf, s1); 131 strcat(buf, s2); 132 return buf; 133} 134 135/* 136 * Parse the unit and subunit from an interface string such as wlXX or wlXX.YY 137 * 138 * @param ifname interface string to parse 139 * @param unit pointer to return the unit number, may pass NULL 140 * @param subunit pointer to return the subunit number, may pass NULL 141 * @return Returns 0 if the string ends with digits or digits.digits, -1 otherwise. 142 * If ifname ends in digits.digits, then unit and subuint are set 143 * to the first and second values respectively. If ifname ends 144 * in just digits, unit is set to the value, and subunit is set 145 * to -1. On error both unit and subunit are -1. NULL may be passed 146 * for unit and/or subuint to ignore the value. 147 */ 148extern int get_ifname_unit(const char* ifname, int *unit, int *subunit); 149 150/* 151 * Get interfaces belonging to a specific bridge. 152 * 153 * @param bridge_name pointer to bridge interface name 154 * @return list on interfaces beloging to the bridge 155 */ 156extern char * 157get_bridged_interfaces(char *bridge_name); 158 159/* 160 remove_from_list 161 Remove the specified word from the list. 162 163 @param name word to be removed from the list 164 @param list List to modify 165 @param listsize Max size the list can occupy 166 167 @return error code 168*/ 169extern int remove_from_list(const char *name, char *list, int listsize); 170 171/* 172 add_to_list 173 Add the specified interface(string) to the list as long as 174 it will fit in the space left in the list. 175 176 @param name Name of interface to be added to the list 177 @param list List to modify 178 @param listsize Max size the list can occupy 179 180 @return error code 181*/ 182extern int add_to_list(const char *name, char *list, int listsize); 183 184extern char *find_in_list(const char *haystack, const char *needle); 185 186extern int nvifname_to_osifname(const char *nvifname, char *osifname_buf, 187 int osifname_buf_len); 188extern int osifname_to_nvifname(const char *osifname, char *nvifname_buf, 189 int nvifname_buf_len); 190 191extern char *remove_dups(char *inlist, int inlist_size); 192 193int ure_any_enabled(void); 194 195#if !defined(__NetBSD__) && !defined(__ARM_ARCH_7A__) 196/* Check for a blank character; that is, a space or a tab */ 197#define isblank(c) ((c) == ' ' || (c) == '\t') 198#endif 199 200/* Strip trailing CR/NL from string <s> */ 201#define chomp(s) ({ \ 202 char *c = (s) + strlen((s)) - 1; \ 203 while ((c > (s)) && (*c == '\n' || *c == '\r')) \ 204 *c-- = '\0'; \ 205 s; \ 206}) 207 208/* Simple version of _backtick() */ 209#define backtick(cmd, args...) ({ \ 210 char *argv[] = { cmd , ## args, NULL }; \ 211 _backtick(argv); \ 212}) 213 214/* Simple version of _eval() (no timeout and wait for child termination) */ 215#define eval(cmd, args...) ({ \ 216 char *argv[] = { cmd , ## args, NULL }; \ 217 _eval(argv, ">/dev/console", 0, NULL); \ 218}) 219 220/* Copy each token in wordlist delimited by space into word */ 221#define foreach(word, wordlist, next) \ 222 for (next = &wordlist[strspn(wordlist, " ")], \ 223 strncpy(word, next, sizeof(word)), \ 224 word[strcspn(word, " ")] = '\0', \ 225 word[sizeof(word) - 1] = '\0', \ 226 next = strchr(next, ' '); \ 227 strlen(word); \ 228 next = next ? &next[strspn(next, " ")] : "", \ 229 strncpy(word, next, sizeof(word)), \ 230 word[strcspn(word, " ")] = '\0', \ 231 word[sizeof(word) - 1] = '\0', \ 232 next = strchr(next, ' ')) 233 234/* Return NUL instead of NULL if undefined */ 235#define safe_getenv(s) (getenv(s) ? : "") 236 237#if defined(linux) || defined(__NetBSD__) 238/* Print directly to the console */ 239 240#define cprintf(fmt, args...) do { \ 241 FILE *fp = fopen("/dev/console", "w"); \ 242 if (fp) { \ 243 fprintf(fp, fmt , ## args); \ 244 fclose(fp); \ 245 } \ 246} while (0) 247#endif 248 249/* Debug print */ 250#ifdef DEBUG 251#define dprintf(fmt, args...) cprintf("%s: " fmt, __FUNCTION__ , ## args) 252#else 253#define dprintf(fmt, args...) 254#endif /* DEBUG */ 255 256 257#ifdef __ECOS 258char * strsep(char **stringp, const char *delim); 259#endif /* __ECOS */ 260 261#endif /* _shutils_h_ */ 262