dgaudet 98/04/19 12:19:39
Modified: src CHANGES
src/ap ap_snprintf.c
src/include ap.h
src/modules/standard mod_access.c
Log:
add %pA, %pI, and %pp format codes
Reviewed by: Martin Kraemer
Revision Changes Path
1.776 +4 -0 apache-1.3/src/CHANGES
Index: CHANGES
===================================================================
RCS file: /export/home/cvs/apache-1.3/src/CHANGES,v
retrieving revision 1.775
retrieving revision 1.776
diff -u -r1.775 -r1.776
--- CHANGES 1998/04/19 16:03:40 1.775
+++ CHANGES 1998/04/19 19:19:35 1.776
@@ -1,5 +1,9 @@
Changes with Apache 1.3b7
+ *) Add %pA, %pI, and %pp codes to ap_vformatter (and hence ap_bprintf,
+ ap_snprintf, and ap_psprintf). See include/ap.h for docs.
+ [Dean Gaudet]
+
*) Because /usr/local/apache is the default prefix the ``configure
--compat'' option no longer has to set prefix, again. This way the
--compat option honors a leading --prefix option. [Lars Eilebrecht]
1.19 +119 -37 apache-1.3/src/ap/ap_snprintf.c
Index: ap_snprintf.c
===================================================================
RCS file: /export/home/cvs/apache-1.3/src/ap/ap_snprintf.c,v
retrieving revision 1.18
retrieving revision 1.19
diff -u -r1.18 -r1.19
--- ap_snprintf.c 1998/03/31 12:52:13 1.18
+++ ap_snprintf.c 1998/04/19 19:19:36 1.19
@@ -384,6 +384,43 @@
+static char *conv_in_addr(struct in_addr *ia, char *buf_end, int *len)
+{
+ unsigned addr = ntohl(ia->s_addr);
+ char *p = buf_end;
+ bool_int is_negative;
+ int sub_len;
+
+ p = conv_10((addr & 0x000000FF) , TRUE, &is_negative, p, &sub_len);
+ *--p = '.';
+ p = conv_10((addr & 0x0000FF00) >> 8, TRUE, &is_negative, p, &sub_len);
+ *--p = '.';
+ p = conv_10((addr & 0x00FF0000) >> 16, TRUE, &is_negative, p, &sub_len);
+ *--p = '.';
+ p = conv_10((addr & 0xFF000000) >> 24, TRUE, &is_negative, p, &sub_len);
+
+ *len = buf_end - p;
+ return (p);
+}
+
+
+
+static char *conv_sockaddr_in(struct sockaddr_in *si, char *buf_end, int
*len)
+{
+ char *p = buf_end;
+ bool_int is_negative;
+ int sub_len;
+
+ p = conv_10(ntohs(si->sin_port), TRUE, &is_negative, p, &sub_len);
+ *--p = ':';
+ p = conv_in_addr(&si->sin_addr, p, &sub_len);
+
+ *len = buf_end - p;
+ return (p);
+}
+
+
+
/*
* Convert a floating point number to a string formats 'f', 'e' or 'E'.
* The result is placed in buf, and len denotes the length of the string
@@ -660,33 +697,27 @@
i_num = va_arg(ap, u_wide_int);
else
i_num = (wide_int) va_arg(ap, unsigned int);
- /*
- * The rest also applies to other integer formats, so fall
- * into that case.
- */
+ s = conv_10(i_num, 1, &is_negative,
+ &num_buf[NUM_BUF_SIZE], &s_len);
+ FIX_PRECISION(adjust_precision, precision, s, s_len);
+ break;
+
case 'd':
case 'i':
- /*
- * Get the arg if we haven't already.
- */
- if ((*fmt) != 'u') {
- if (is_long)
- i_num = va_arg(ap, wide_int);
- else
- i_num = (wide_int) va_arg(ap, int);
- };
- s = conv_10(i_num, (*fmt) == 'u', &is_negative,
+ if (is_long)
+ i_num = va_arg(ap, wide_int);
+ else
+ i_num = (wide_int) va_arg(ap, int);
+ s = conv_10(i_num, 0, &is_negative,
&num_buf[NUM_BUF_SIZE], &s_len);
FIX_PRECISION(adjust_precision, precision, s, s_len);
- if (*fmt != 'u') {
- if (is_negative)
- prefix_char = '-';
- else if (print_sign)
- prefix_char = '+';
- else if (print_blank)
- prefix_char = ' ';
- }
+ if (is_negative)
+ prefix_char = '-';
+ else if (print_sign)
+ prefix_char = '+';
+ else if (print_blank)
+ prefix_char = ' ';
break;
@@ -801,26 +832,77 @@
break;
/*
- * Always extract the argument as a "char *" pointer. We
- * should be using "void *" but there are still machines
- * that don't understand it.
- * If the pointer size is equal to the size of an unsigned
- * integer we convert the pointer to a hex number, otherwise
- * we print "%p" to indicate that we don't handle "%p".
+ * This is where we extend the printf format, with a second
+ * type specifier
*/
case 'p':
- ui_num = (u_wide_int) va_arg(ap, char *);
+ switch(*++fmt) {
+ /*
+ * If the pointer size is equal to the size of an unsigned
+ * integer we convert the pointer to a hex number,
otherwise
+ * we print "%p" to indicate that we don't handle "%p".
+ */
+ case 'p':
+ ui_num = (u_wide_int) va_arg(ap, void *);
+
+ if (sizeof(char *) <= sizeof(u_wide_int))
+ s = conv_p2(ui_num, 4, 'x',
+ &num_buf[NUM_BUF_SIZE], &s_len);
+ else {
+ s = "%p";
+ s_len = 2;
+ }
+ pad_char = ' ';
+ break;
- if (sizeof(char *) <= sizeof(u_wide_int))
- s = conv_p2(ui_num, 4, 'x',
- &num_buf[NUM_BUF_SIZE], &s_len);
- else {
- s = "%p";
- s_len = 2;
+ /* print a struct sockaddr_in as a.b.c.d:port */
+ case 'I':
+ {
+ struct sockaddr_in *si;
+
+ si = va_arg(ap, struct sockaddr_in *);
+ if (si != NULL) {
+ s = conv_sockaddr_in(si, &num_buf[NUM_BUF_SIZE],
&s_len);
+ if (adjust_precision && precision < s_len)
+ s_len = precision;
+ }
+ else {
+ s = S_NULL;
+ s_len = S_NULL_LEN;
+ }
+ pad_char = ' ';
+ }
+ break;
+
+ /* print a struct in_addr as a.b.c.d */
+ case 'A':
+ {
+ struct in_addr *ia;
+
+ ia = va_arg(ap, struct in_addr *);
+ if (ia != NULL) {
+ s = conv_in_addr(ia, &num_buf[NUM_BUF_SIZE],
&s_len);
+ if (adjust_precision && precision < s_len)
+ s_len = precision;
+ }
+ else {
+ s = S_NULL;
+ s_len = S_NULL_LEN;
+ }
+ pad_char = ' ';
+ }
+ break;
+
+ case NUL:
+ /* if %p ends the string, oh well ignore it */
+ continue;
+
+ default:
+ s = "bogus %p";
+ s_len = 8;
+ break;
}
- pad_char = ' ';
break;
-
case NUL:
/*
1.12 +15 -2 apache-1.3/src/include/ap.h
Index: ap.h
===================================================================
RCS file: /export/home/cvs/apache-1.3/src/include/ap.h,v
retrieving revision 1.11
retrieving revision 1.12
diff -u -r1.11 -r1.12
--- ap.h 1998/03/31 12:52:17 1.11
+++ ap.h 1998/04/19 19:19:37 1.12
@@ -81,8 +81,21 @@
#endif
#endif /* WIN32 */
-/* ap_vformatter() is a generic printf-style formatting routine
- * with some extensions.
+/* apapi_vformatter() is a generic printf-style formatting routine
+ * with some extensions. The extensions are:
+ *
+ * %pA takes a struct in_addr *, and prints it as a.b.c.d
+ * %pI takes a struct sockaddr_in * and prints it as a.b.c.d:port
+ * %pp takes a void * and outputs it in hex
+ *
+ * The %p hacks are to force gcc's printf warning code to skip
+ * over a pointer argument without complaining. This does
+ * mean that the ANSI-style %p (output a void * in hex format) won't
+ * work as expected at all, but that seems to be a fair trade-off
+ * for the increased robustness of having printf-warnings work.
+ *
+ * Additionally, apapi_vformatter allows for arbitrary output methods
+ * using the apapi_vformatter_buff and flush_func.
*
* The ap_vformatter_buff has two elements curpos and endpos.
* curpos is where ap_vformatter will write the next byte of output.
1.35 +2 -1 apache-1.3/src/modules/standard/mod_access.c
Index: mod_access.c
===================================================================
RCS file: /export/home/cvs/apache-1.3/src/modules/standard/mod_access.c,v
retrieving revision 1.34
retrieving revision 1.35
diff -u -r1.34 -r1.35
--- mod_access.c 1998/04/11 12:00:43 1.34
+++ mod_access.c 1998/04/19 19:19:38 1.35
@@ -377,7 +377,8 @@
if (ret == FORBIDDEN
&& (ap_satisfies(r) != SATISFY_ANY || !ap_some_auth_required(r))) {
ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, r->server,
- "Client denied by server configuration: %s", r->filename);
+ "client %pI denied by server configuration: %s",
+ &r->connection->remote_addr, r->filename);
}
return ret;