1/* 2 * Shell-like utility functions 3 * 4 * Copyright 2005, Broadcom Corporation 5 * All Rights Reserved. 6 * 7 * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY 8 * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM 9 * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS 10 * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. 11 * 12 * $Id: shutils.h,v 1.8 2005/03/07 08:35:32 kanki Exp $ 13 */ 14 15#ifndef _shutils_h_ 16#define _shutils_h_ 17#include <string.h> 18#include <rtconfig.h> 19 20#ifndef MAX_NVPARSE 21#define MAX_NVPARSE 16 22#endif 23#define sin_addr(s) (((struct sockaddr_in *)(s))->sin_addr) 24 25#ifndef max 26#define max(a,b) (((a) > (b)) ? (a) : (b)) 27#endif /* max */ 28 29#ifndef min 30#define min(a,b) (((a) < (b)) ? (a) : (b)) 31#endif /* min */ 32 33#define ENC_XOR (0x74) 34#define DATA_WORDS_LEN (120) 35#define ENC_WORDS_LEN (384) 36 37extern int doSystem(char *fmt, ...); 38 39/* 40 * Reads file and returns contents 41 * @param fd file descriptor 42 * @return contents of file or NULL if an error occurred 43 */ 44extern char * fd2str(int fd); 45 46/* 47 * Reads file and returns contents 48 * @param path path to file 49 * @return contents of file or NULL if an error occurred 50 */ 51extern char * file2str(const char *path); 52 53/* 54 * Waits for a file descriptor to become available for reading or unblocked signal 55 * @param fd file descriptor 56 * @param timeout seconds to wait before timing out or 0 for no timeout 57 * @return 1 if descriptor changed status or 0 if timed out or -1 on error 58 */ 59extern int waitfor(int fd, int timeout); 60 61/* 62 * Concatenates NULL-terminated list of arguments into a single 63 * commmand and executes it 64 * @param argv argument list 65 * @param path NULL, ">output", or ">>output" 66 * @param timeout seconds to wait before timing out or 0 for no timeout 67 * @param ppid NULL to wait for child termination or pointer to pid 68 * @return return value of executed command or errno 69 */ 70extern int _eval(char *const argv[], const char *path, int timeout, pid_t *ppid); 71 72/* 73 * Evaluate cmds using taskset while SMP. 74 * @param ppid NULL to wait for child termination or pointer to pid 75 * @param cmds command argument list 76 * The normal command elements protype is as [cpu0/cpu1], [cmd_arg0, cmd_arg1, ..., NULL] 77 * If smp defined, it should specify cpu0/cpu1 at the fist element, 78 * if it is not specified, cpu0 will be the default choice. 79 * On UP case, no need to specify cpu0/1, otherwise will be ignored. 80 */ 81#define CPU0 "0" 82#define CPU1 "1" 83 84extern int _cpu_eval(int *ppid, char *cmds[]); 85 86/* 87 * Concatenates NULL-terminated list of arguments into a single 88 * commmand and executes it 89 * @param argv argument list 90 * @return stdout of executed command or NULL if an error occurred 91 */ 92// extern char * _backtick(char *const argv[]); 93 94/* 95 * Kills process whose PID is stored in plaintext in pidfile 96 * @param pidfile PID file 97 * @return 0 on success and errno on failure 98 */ 99extern int kill_pidfile(char *pidfile); 100extern int kill_pidfile_s(char *pidfile, int sig); 101extern int kill_pidfile_s_rm(char *pidfile, int sig); 102 103/* 104 * fread() with automatic retry on syscall interrupt 105 * @param ptr location to store to 106 * @param size size of each element of data 107 * @param nmemb number of elements 108 * @param stream file stream 109 * @return number of items successfully read 110 */ 111extern int safe_fread(void *ptr, size_t size, size_t nmemb, FILE *stream); 112 113/* 114 * fwrite() with automatic retry on syscall interrupt 115 * @param ptr location to read from 116 * @param size size of each element of data 117 * @param nmemb number of elements 118 * @param stream file stream 119 * @return number of items successfully written 120 */ 121extern int safe_fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream); 122 123/* 124 * Convert Ethernet address string representation to binary data 125 * @param a string in xx:xx:xx:xx:xx:xx notation 126 * @param e binary data 127 * @return TRUE if conversion was successful and FALSE otherwise 128 */ 129extern int ether_atoe(const char *a, unsigned char *e); 130 131/* 132 * Convert Ethernet address binary data to string representation 133 * @param e binary data 134 * @param a string in xx:xx:xx:xx:xx:xx notation 135 * @return a 136 */ 137extern char * ether_etoa(const unsigned char *e, char *a); 138 139/* 140 * Concatenate two strings together into a caller supplied buffer 141 * @param s1 first string 142 * @param s2 second string 143 * @param buf buffer large enough to hold both strings 144 * @return buf 145 */ 146static inline char * strcat_r(const char *s1, const char *s2, char *buf) 147{ 148 strcpy(buf, s1); 149 strcat(buf, s2); 150 return buf; 151} 152 153/* Strip trailing CR/NL from string <s> */ 154#define chomp(s) ({ \ 155 char *c = (s) + strlen((s)) - 1; \ 156 while ((c > (s)) && (*c == '\n' || *c == '\r' || *c == ' ')) \ 157 *c-- = '\0'; \ 158 s; \ 159}) 160 161 162/* Simple version of _eval() (no timeout and wait for child termination) */ 163#if 1 164#define eval(cmd, args...) ({ \ 165 char * const argv[] = { cmd, ## args, NULL }; \ 166 _eval(argv, NULL, 0, NULL); \ 167}) 168#else 169#define eval(cmd, args...) ({ \ 170 char * const argv[] = { cmd, ## args, NULL }; \ 171 _eval(argv, ">/dev/console", 0, NULL); \ 172}) 173#endif 174 175/* another _cpu_eval form */ 176#define cpu_eval(ppid, cmd, args...) ({ \ 177 char * argv[] = { cmd, ## args, NULL }; \ 178 _cpu_eval(ppid, argv); \ 179}) 180 181/* Copy each token in wordlist delimited by space into word */ 182#define foreach(word, wordlist, next) \ 183 for (next = &wordlist[strspn(wordlist, " ")], \ 184 strncpy(word, next, sizeof(word)), \ 185 word[strcspn(word, " ")] = '\0', \ 186 word[sizeof(word) - 1] = '\0', \ 187 next = strchr(next, ' '); \ 188 strlen(word); \ 189 next = next ? &next[strspn(next, " ")] : "", \ 190 strncpy(word, next, sizeof(word)), \ 191 word[strcspn(word, " ")] = '\0', \ 192 word[sizeof(word) - 1] = '\0', \ 193 next = strchr(next, ' ')) 194 195/* Copy each token in wordlist delimited by ascii_44 into word */ 196#define foreach_44(word, wordlist, next) \ 197 for (next = &wordlist[strspn(wordlist, ",")], \ 198 strncpy(word, next, sizeof(word)), \ 199 word[strcspn(word, ",")] = '\0', \ 200 word[sizeof(word) - 1] = '\0', \ 201 next = strchr(next, ','); \ 202 strlen(word); \ 203 next = next ? &next[strspn(next, ",")] : "", \ 204 strncpy(word, next, sizeof(word)), \ 205 word[strcspn(word, ",")] = '\0', \ 206 word[sizeof(word) - 1] = '\0', \ 207 next = strchr(next, ',')) 208 209/* Copy each token in wordlist delimited by ascii_58 into word */ 210#define foreach_58(word, wordlist, next) \ 211 for (next = &wordlist[strspn(wordlist, ":")], \ 212 strncpy(word, next, sizeof(word)), \ 213 word[strcspn(word, ":")] = '\0', \ 214 word[sizeof(word) - 1] = '\0', \ 215 next = strchr(next, ':'); \ 216 strlen(word); \ 217 next = next ? &next[strspn(next, ":")] : "", \ 218 strncpy(word, next, sizeof(word)), \ 219 word[strcspn(word, ":")] = '\0', \ 220 word[sizeof(word) - 1] = '\0', \ 221 next = strchr(next, ':')) 222 223/* Copy each token in wordlist delimited by ascii_60 into word */ 224#define foreach_60(word, wordlist, next) \ 225 for (next = &wordlist[strspn(wordlist, "<")], \ 226 strncpy(word, next, sizeof(word)), \ 227 word[strcspn(word, "<")] = '\0', \ 228 word[sizeof(word) - 1] = '\0', \ 229 next = strchr(next, '<'); \ 230 strlen(word); \ 231 next = next ? &next[strspn(next, "<")] : "", \ 232 strncpy(word, next, sizeof(word)), \ 233 word[strcspn(word, "<")] = '\0', \ 234 word[sizeof(word) - 1] = '\0', \ 235 next = strchr(next, '<')) 236 237/* Copy each token in wordlist delimited by ascii_62 into word */ 238#define foreach_62(word, wordlist, next) \ 239 for (next = &wordlist[strspn(wordlist, ">")], \ 240 strncpy(word, next, sizeof(word)), \ 241 word[strcspn(word, ">")] = '\0', \ 242 word[sizeof(word) - 1] = '\0', \ 243 next = strchr(next, '>'); \ 244 strlen(word); \ 245 next = next ? &next[strspn(next, ">")] : "", \ 246 strncpy(word, next, sizeof(word)), \ 247 word[strcspn(word, ">")] = '\0', \ 248 word[sizeof(word) - 1] = '\0', \ 249 next = strchr(next, '>')) 250 251/* Return NUL instead of NULL if undefined */ 252#define safe_getenv(s) (getenv(s) ? : "") 253 254#define ONE_ENTRANT() \ 255do { \ 256 static int served = 0; \ 257 if(served ++ > 0) \ 258 return; \ 259} while (0) 260 261//#define dbg(fmt, args...) do { FILE *fp = fopen("/dev/console", "w"); if (fp) { fprintf(fp, fmt, ## args); fclose(fp); } else fprintf(stderr, fmt, ## args); } while (0) 262extern void dbg(const char * format, ...); 263#define dbG(fmt, args...) dbg("%s(0x%04x): " fmt , __FUNCTION__ , __LINE__, ## args) 264extern void cprintf(const char *format, ...); 265 266 267/* 268 * Parse the unit and subunit from an interface string such as wlXX or wlXX.YY 269 * 270 * @param ifname interface string to parse 271 * @param unit pointer to return the unit number, may pass NULL 272 * @param subunit pointer to return the subunit number, may pass NULL 273 * @return Returns 0 if the string ends with digits or digits.digits, -1 otherwise. 274 * If ifname ends in digits.digits, then unit and subuint are set 275 * to the first and second values respectively. If ifname ends 276 * in just digits, unit is set to the value, and subunit is set 277 * to -1. On error both unit and subunit are -1. NULL may be passed 278 * for unit and/or subuint to ignore the value. 279 */ 280extern int get_ifname_unit(const char* ifname, int *unit, int *subunit); 281 282/* 283 * Set the ip configuration index given the eth name 284 * Updates both wlXX_ipconfig_index and lanYY_ifname. 285 * 286 * @param eth_ifname pointer to eth interface name 287 * @return 0 if successful -1 if not. 288 */ 289extern int set_ipconfig_index(char *eth_ifname, int index); 290 291/* 292 * Get the ip configuration index if it exists given the 293 * eth name. 294 * 295 * @param wl_ifname pointer to eth interface name 296 * @return index or -1 if not found 297 */ 298extern int get_ipconfig_index(char *eth_ifname); 299 300/* 301 * Get interfaces belonging to a specific bridge. 302 * 303 * @param bridge_name pointer to bridge interface name 304 * @return list on interfaces beloging to the bridge 305 */ 306extern char * 307get_bridged_interfaces(char *bridge_name); 308 309/* 310 remove_from_list 311 Remove the specified word from the list. 312 313 @param name word to be removed from the list 314 @param list List to modify 315 @param listsize Max size the list can occupy 316 317 @return error code 318*/ 319extern int remove_from_list(const char *name, char *list, int listsize); 320 321/* 322 add_to_list 323 Add the specified interface(string) to the list as long as 324 it will fit in the space left in the list. 325 326 @param name Name of interface to be added to the list 327 @param list List to modify 328 @param listsize Max size the list can occupy 329 330 @return error code 331*/ 332extern int add_to_list(const char *name, char *list, int listsize); 333 334extern char *find_in_list(const char *haystack, const char *needle); 335 336extern char *remove_dups(char *inlist, int inlist_size); 337 338extern int nvifname_to_osifname(const char *nvifname, char *osifname_buf, 339 int osifname_buf_len); 340extern int osifname_to_nvifname(const char *osifname, char *nvifname_buf, 341 int nvifname_buf_len); 342 343int ure_any_enabled(void); 344 345#define is_hwnat_loaded() module_loaded("hw_nat") 346 347#define vstrsep(buf, sep, args...) _vstrsep(buf, sep, args, NULL) 348extern int _vstrsep(char *buf, const char *sep, ...); 349 350/* Buffer structure for collecting string-formatted data 351 * using str_bprintf() API. 352 * Use str_binit() to initialize before use 353 */ 354struct strbuf { 355 char *buf; /* pointer to current position in origbuf */ 356 unsigned int size; /* current (residual) size in bytes */ 357 char *origbuf; /* unmodified pointer to orignal buffer */ 358 unsigned int origsize; /* unmodified orignal buffer size in bytes */ 359}; 360 361extern void str_binit(struct strbuf *b, char *buf, unsigned int size); 362extern int str_bprintf(struct strbuf *b, const char *fmt, ...); 363 364#endif /* _shutils_h_ */ 365 366extern int strArgs(int argc, char **argv, char *fmt, ...); 367extern char *trimNL(char *str); 368extern pid_t get_pid_by_name(char *name); 369extern char *get_process_name_by_pid(const int pid); 370