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