Commit | Line | Data |
---|---|---|
ec0e5ac0 AT |
1 | /* |
2 | Copyright (C) Andrew Tridgell 1998 | |
e0fde757 | 3 | Copyright (C) 2002 by Martin Pool |
ec0e5ac0 AT |
4 | |
5 | This program is free software; you can redistribute it and/or modify | |
6 | it under the terms of the GNU General Public License as published by | |
7 | the Free Software Foundation; either version 2 of the License, or | |
8 | (at your option) any later version. | |
9 | ||
10 | This program is distributed in the hope that it will be useful, | |
11 | but WITHOUT ANY WARRANTY; without even the implied warranty of | |
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
13 | GNU General Public License for more details. | |
14 | ||
15 | You should have received a copy of the GNU General Public License | |
16 | along with this program; if not, write to the Free Software | |
17 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | |
18 | */ | |
19 | ||
e0fde757 MP |
20 | /** |
21 | * @file compat.c | |
22 | * | |
23 | * Reimplementations of standard functions for platforms that don't | |
24 | * have them. | |
25 | **/ | |
26 | ||
27 | ||
ec0e5ac0 | 28 | |
ec0e5ac0 AT |
29 | #include "rsync.h" |
30 | ||
31 | ||
32 | #ifndef HAVE_STRDUP | |
33 | char *strdup(char *s) | |
34 | { | |
35 | int l = strlen(s) + 1; | |
36 | char *ret = (char *)malloc(l); | |
37 | if (ret) | |
38 | strcpy(ret,s); | |
39 | return ret; | |
40 | } | |
41 | #endif | |
42 | ||
43 | #ifndef HAVE_GETCWD | |
5a788ade | 44 | char *getcwd(char *buf, int size) |
ec0e5ac0 AT |
45 | { |
46 | return getwd(buf); | |
47 | } | |
48 | #endif | |
49 | ||
50 | ||
51 | #ifndef HAVE_WAITPID | |
5a788ade | 52 | pid_t waitpid(pid_t pid, int *statptr, int options) |
ec0e5ac0 | 53 | { |
e68f3481 | 54 | #ifdef HAVE_WAIT4 |
ec0e5ac0 | 55 | return wait4(pid, statptr, options, NULL); |
e68f3481 DD |
56 | #else |
57 | /* If wait4 is also not available, try wait3 for SVR3 variants */ | |
58 | /* Less ideal because can't actually request a specific pid */ | |
59 | /* At least the WNOHANG option is supported */ | |
60 | /* Code borrowed from apache fragment written by dwd@bell-labs.com */ | |
61 | int tmp_pid, dummystat;; | |
62 | if (kill(pid, 0) == -1) { | |
63 | errno = ECHILD; | |
64 | return -1; | |
65 | } | |
66 | if (statptr == NULL) | |
67 | statptr = &dummystat; | |
68 | while (((tmp_pid = wait3(statptr, options, 0)) != pid) && | |
69 | (tmp_pid != -1) && (tmp_pid != 0) && (pid != -1)) | |
70 | ; | |
71 | return tmp_pid; | |
72 | #endif | |
ec0e5ac0 AT |
73 | } |
74 | #endif | |
75 | ||
9fc310da AT |
76 | |
77 | #ifndef HAVE_MEMMOVE | |
5a788ade | 78 | void *memmove(void *dest, const void *src, size_t n) |
9fc310da | 79 | { |
52d7d788 | 80 | bcopy((char *) src, (char *) dest, n); |
9fc310da AT |
81 | return dest; |
82 | } | |
83 | #endif | |
2b6b4d53 AT |
84 | |
85 | #ifndef HAVE_STRPBRK | |
e0fde757 MP |
86 | /** |
87 | * Find the first ocurrence in @p s of any character in @p accept. | |
88 | * | |
89 | * Derived from glibc | |
90 | **/ | |
5a788ade | 91 | char *strpbrk(const char *s, const char *accept) |
2b6b4d53 AT |
92 | { |
93 | while (*s != '\0') { | |
94 | const char *a = accept; | |
95 | while (*a != '\0') { | |
96 | if (*a++ == *s) return (char *)s; | |
97 | } | |
98 | ++s; | |
99 | } | |
100 | ||
101 | return NULL; | |
102 | } | |
103 | #endif | |
7b3d4257 | 104 | |
5a788ade AT |
105 | |
106 | #ifndef HAVE_STRLCPY | |
e0fde757 MP |
107 | /** |
108 | * Like strncpy but does not 0 fill the buffer and always null | |
109 | * terminates. | |
110 | * | |
111 | * @param bufsize is the size of the destination buffer. | |
c7677b89 | 112 | * |
e0fde757 MP |
113 | * @return index of the terminating byte. |
114 | **/ | |
5a788ade AT |
115 | size_t strlcpy(char *d, const char *s, size_t bufsize) |
116 | { | |
117 | size_t len = strlen(s); | |
118 | size_t ret = len; | |
72d45525 WD |
119 | if (bufsize > 0) { |
120 | if (len >= bufsize) | |
121 | len = bufsize-1; | |
122 | memcpy(d, s, len); | |
123 | d[len] = 0; | |
124 | } | |
5a788ade AT |
125 | return ret; |
126 | } | |
127 | #endif | |
128 | ||
129 | #ifndef HAVE_STRLCAT | |
e0fde757 MP |
130 | /** |
131 | * Like strncat() but does not 0 fill the buffer and always null | |
132 | * terminates. | |
133 | * | |
134 | * @param bufsize length of the buffer, which should be one more than | |
135 | * the maximum resulting string length. | |
136 | **/ | |
5a788ade AT |
137 | size_t strlcat(char *d, const char *s, size_t bufsize) |
138 | { | |
139 | size_t len1 = strlen(d); | |
140 | size_t len2 = strlen(s); | |
141 | size_t ret = len1 + len2; | |
142 | ||
1fb8ec4b WD |
143 | if (len1 < bufsize - 1) { |
144 | if (len2 >= bufsize - len1) | |
145 | len2 = bufsize - len1 - 1; | |
5a788ade AT |
146 | memcpy(d+len1, s, len2); |
147 | d[len1+len2] = 0; | |
148 | } | |
149 | return ret; | |
150 | } | |
151 | #endif | |
b17bc22b | 152 | |
fca3ef06 AT |
153 | #ifdef REPLACE_INET_NTOA |
154 | char *rep_inet_ntoa(struct in_addr ip) | |
155 | { | |
156 | unsigned char *p = (unsigned char *)&ip.s_addr; | |
157 | static char buf[18]; | |
4f5b0756 | 158 | #ifdef WORDS_BIGENDIAN |
65c2a918 | 159 | snprintf(buf, 18, "%d.%d.%d.%d", |
fca3ef06 AT |
160 | (int)p[0], (int)p[1], (int)p[2], (int)p[3]); |
161 | #else | |
65c2a918 | 162 | snprintf(buf, 18, "%d.%d.%d.%d", |
fca3ef06 AT |
163 | (int)p[3], (int)p[2], (int)p[1], (int)p[0]); |
164 | #endif | |
165 | return buf; | |
166 | } | |
167 | #endif | |
168 | ||
269833af | 169 | #ifdef REPLACE_INET_ATON |
b17bc22b AT |
170 | int inet_aton(const char *cp, struct in_addr *inp) |
171 | { | |
5b5591d8 AT |
172 | unsigned int a1, a2, a3, a4; |
173 | unsigned long ret; | |
174 | ||
b17bc22b AT |
175 | if (strcmp(cp, "255.255.255.255") == 0) { |
176 | inp->s_addr = (unsigned) -1; | |
14175f1e | 177 | return 0; |
b17bc22b AT |
178 | } |
179 | ||
5b5591d8 AT |
180 | if (sscanf(cp, "%u.%u.%u.%u", &a1, &a2, &a3, &a4) != 4 || |
181 | a1 > 255 || a2 > 255 || a3 > 255 || a4 > 255) { | |
14175f1e | 182 | return 0; |
5b5591d8 AT |
183 | } |
184 | ||
185 | ret = (a1 << 24) | (a2 << 16) | (a3 << 8) | a4; | |
186 | ||
187 | inp->s_addr = htonl(ret); | |
188 | ||
b17bc22b AT |
189 | if (inp->s_addr == (unsigned) -1) { |
190 | return 0; | |
191 | } | |
192 | return 1; | |
193 | } | |
194 | #endif | |
3060d4aa AT |
195 | |
196 | /* some systems don't take the 2nd argument */ | |
197 | int sys_gettimeofday(struct timeval *tv) | |
198 | { | |
4f5b0756 | 199 | #ifdef HAVE_GETTIMEOFDAY_TZ |
3060d4aa AT |
200 | return gettimeofday(tv, NULL); |
201 | #else | |
202 | return gettimeofday(tv); | |
203 | #endif | |
204 | } |