libs/libpam: port some uclibc xdr code to yppasswd_xdr.c
[openwrt/svn-archive/archive.git] / libs / libpam / patches / 006-fix_xdr.patch
1 --- a/Linux-PAM-1.1.4/modules/pam_unix/yppasswd_xdr.c
2 +++ b/Linux-PAM-1.1.4/modules/pam_unix/yppasswd_xdr.c
3 2011-10-01 13:46:21.599443197 +0300
4 @@ -21,6 +21,268 @@
5 #endif
6 #include "yppasswd.h"
7
8 +#ifdef __UCLIBC__
9 +
10 +static const char xdr_zero[BYTES_PER_XDR_UNIT] = {0, 0, 0, 0};
11 +
12 +/*
13 + * XDR integers
14 + */
15 +bool_t
16 +xdr_int (XDR *xdrs, int *ip)
17 +{
18 +
19 +#if INT_MAX < LONG_MAX
20 + long l;
21 +
22 + switch (xdrs->x_op)
23 + {
24 + case XDR_ENCODE:
25 + l = (long) *ip;
26 + return XDR_PUTLONG (xdrs, &l);
27 +
28 + case XDR_DECODE:
29 + if (!XDR_GETLONG (xdrs, &l))
30 + {
31 + return FALSE;
32 + }
33 + *ip = (int) l;
34 + case XDR_FREE:
35 + return TRUE;
36 + }
37 + return FALSE;
38 +#elif INT_MAX == LONG_MAX
39 + return xdr_long (xdrs, (long *) ip);
40 +#elif INT_MAX == SHRT_MAX
41 + return xdr_short (xdrs, (short *) ip);
42 +#else
43 +#error unexpected integer sizes in xdr_int()
44 +#endif
45 +}
46 +
47 +/*
48 + * XDR null terminated ASCII strings
49 + * xdr_string deals with "C strings" - arrays of bytes that are
50 + * terminated by a NULL character. The parameter cpp references a
51 + * pointer to storage; If the pointer is null, then the necessary
52 + * storage is allocated. The last parameter is the max allowed length
53 + * of the string as specified by a protocol.
54 + */
55 +bool_t
56 +xdr_string (XDR *xdrs, char **cpp, u_int maxsize)
57 +{
58 + char *sp = *cpp; /* sp is the actual string pointer */
59 + u_int size;
60 + u_int nodesize;
61 +
62 + /*
63 + * first deal with the length since xdr strings are counted-strings
64 + */
65 + switch (xdrs->x_op)
66 + {
67 + case XDR_FREE:
68 + if (sp == NULL)
69 + {
70 + return TRUE; /* already free */
71 + }
72 + /* fall through... */
73 + case XDR_ENCODE:
74 + if (sp == NULL)
75 + return FALSE;
76 + size = strlen (sp);
77 + break;
78 + case XDR_DECODE:
79 + break;
80 + }
81 + if (!xdr_u_int (xdrs, &size))
82 + {
83 + return FALSE;
84 + }
85 + if (size > maxsize)
86 + {
87 + return FALSE;
88 + }
89 + nodesize = size + 1;
90 +
91 + /*
92 + * now deal with the actual bytes
93 + */
94 + switch (xdrs->x_op)
95 + {
96 + case XDR_DECODE:
97 + if (nodesize == 0)
98 + {
99 + return TRUE;
100 + }
101 + if (sp == NULL)
102 + *cpp = sp = (char *) mem_alloc (nodesize);
103 + if (sp == NULL)
104 + {
105 +#ifdef USE_IN_LIBIO
106 + if (_IO_fwide (stderr, 0) > 0)
107 + (void) fwprintf (stderr, L"%s",
108 + _("xdr_string: out of memory\n"));
109 + else
110 +#endif
111 + (void) fputs (_("xdr_string: out of memory\n"), stderr);
112 + return FALSE;
113 + }
114 + sp[size] = 0;
115 + /* fall into ... */
116 +
117 + case XDR_ENCODE:
118 + return xdr_opaque (xdrs, sp, size);
119 +
120 + case XDR_FREE:
121 + mem_free (sp, nodesize);
122 + *cpp = NULL;
123 + return TRUE;
124 + }
125 + return FALSE;
126 +}
127 +
128 +/*
129 + * XDR long integers
130 + * The definition of xdr_long() is kept for backward
131 + * compatibility. Instead xdr_int() should be used.
132 + */
133 +bool_t
134 +xdr_long (XDR *xdrs, long *lp)
135 +{
136 + if (xdrs->x_op == XDR_ENCODE
137 + && (sizeof (int32_t) == sizeof (long)
138 + || (int32_t) *lp == *lp))
139 + return XDR_PUTLONG (xdrs, lp);
140 +
141 + if (xdrs->x_op == XDR_DECODE)
142 + return XDR_GETLONG (xdrs, lp);
143 +
144 + if (xdrs->x_op == XDR_FREE)
145 + return TRUE;
146 +
147 + return FALSE;
148 +}
149 +
150 +/*
151 + * XDR unsigned integers
152 + */
153 +bool_t
154 +xdr_u_int (XDR *xdrs, u_int *up)
155 +{
156 +#if UINT_MAX < ULONG_MAX
157 + u_long l;
158 +
159 + switch (xdrs->x_op)
160 + {
161 + case XDR_ENCODE:
162 + l = (u_long) * up;
163 + return XDR_PUTLONG (xdrs, (long *) &l);
164 +
165 + case XDR_DECODE:
166 + if (!XDR_GETLONG (xdrs, (long *) &l))
167 + {
168 + return FALSE;
169 + }
170 + *up = (u_int) l;
171 + case XDR_FREE:
172 + return TRUE;
173 + }
174 + return FALSE;
175 +#elif UINT_MAX == ULONG_MAX
176 + return xdr_u_long (xdrs, (u_long *) up);
177 +#elif UINT_MAX == USHRT_MAX
178 + return xdr_short (xdrs, (short *) up);
179 +#else
180 +#error unexpected integer sizes in xdr_u_int()
181 +#endif
182 +}
183 +
184 +/*
185 + * XDR opaque data
186 + * Allows the specification of a fixed size sequence of opaque bytes.
187 + * cp points to the opaque object and cnt gives the byte length.
188 + */
189 +bool_t
190 +xdr_opaque (XDR *xdrs, caddr_t cp, u_int cnt)
191 +{
192 + u_int rndup;
193 + static char crud[BYTES_PER_XDR_UNIT];
194 +
195 + /*
196 + * if no data we are done
197 + */
198 + if (cnt == 0)
199 + return TRUE;
200 +
201 + /*
202 + * round byte count to full xdr units
203 + */
204 + rndup = cnt % BYTES_PER_XDR_UNIT;
205 + if (rndup > 0)
206 + rndup = BYTES_PER_XDR_UNIT - rndup;
207 +
208 + switch (xdrs->x_op)
209 + {
210 + case XDR_DECODE:
211 + if (!XDR_GETBYTES (xdrs, cp, cnt))
212 + {
213 + return FALSE;
214 + }
215 + if (rndup == 0)
216 + return TRUE;
217 + return XDR_GETBYTES (xdrs, (caddr_t)crud, rndup);
218 +
219 + case XDR_ENCODE:
220 + if (!XDR_PUTBYTES (xdrs, cp, cnt))
221 + {
222 + return FALSE;
223 + }
224 + if (rndup == 0)
225 + return TRUE;
226 + return XDR_PUTBYTES (xdrs, xdr_zero, rndup);
227 +
228 + case XDR_FREE:
229 + return TRUE;
230 + }
231 + return FALSE;
232 +}
233 +
234 +/*
235 + * XDR unsigned long integers
236 + * The definition of xdr_u_long() is kept for backward
237 + * compatibility. Instead xdr_u_int() should be used.
238 + */
239 +bool_t
240 +xdr_u_long (XDR *xdrs, u_long *ulp)
241 +{
242 + switch (xdrs->x_op)
243 + {
244 + case XDR_DECODE:
245 + {
246 + long int tmp;
247 +
248 + if (XDR_GETLONG (xdrs, &tmp) == FALSE)
249 + return FALSE;
250 +
251 + *ulp = (uint32_t) tmp;
252 + return TRUE;
253 + }
254 +
255 + case XDR_ENCODE:
256 + if (sizeof (uint32_t) != sizeof (u_long)
257 + && (uint32_t) *ulp != *ulp)
258 + return FALSE;
259 +
260 + return XDR_PUTLONG (xdrs, (long *) ulp);
261 +
262 + case XDR_FREE:
263 + return TRUE;
264 + }
265 + return FALSE;
266 +}
267 +
268 +#endif /* UCLIBC */
269 +
270 bool_t
271 xdr_xpasswd(XDR * xdrs, xpasswd * objp)
272 {