[PATCH] Update man page for init file, one nroff format error
17 years, 6 months
Shyamal Prasad
etc/ChangeLog addition:
2004-12-03 Shyamal Prasad <shyamal(a)member.fsf.org>
* xemacs.1: Now describe $HOME/.xemacs/init.el as the
preferred init file. Fixed excessive space insertion
in the description of the '-vanilla' option
XEmacs source patch:
Diff command: cvs -q diff -u
Files affected: etc/xemacs.1
Index: etc/xemacs.1
===================================================================
RCS file: /pack/xemacscvs/XEmacs/xemacs/etc/xemacs.1,v
retrieving …
[View More]revision 1.13
diff -u -r1.13 xemacs.1
--- etc/xemacs.1 2001/04/12 18:20:52 1.13
+++ etc/xemacs.1 2004/12/04 01:33:45
@@ -147,12 +147,7 @@
.TP
.B \-vanilla
Load no extra files at startup. Equivalent to the combination of
-.B \-q
-,
-.B \-no-site-file
-, and
-.B \-no-early-packages
-\.
+.BR \-q ", " \-no-site-file ", and " \-no-early-packages .
.TP
.BI \-u " user, " \-user " user"
Load
@@ -628,7 +623,8 @@
META-left Make a rectangular selection.
.SH FILES
Lisp code is read at startup from the user's init file,
-\fB$HOME/.emacs\fP.
+\fB$HOME/.xemacs/init.el\fP. If this file does not exist then
+\fB$HOME/.emacs\fP will be read if it is present.
/usr/local/info - files for the Info documentation browser
(a subsystem of
[View Less]
[PATCH] Synch up format-time-string % specifiers with Emacs 21.3.1
17 years, 6 months
Shyamal Prasad
This patch adds % specifiers to format-time-string that are missing in
XEmacs but supported by Emacs 21.3.1
src/ChangeLog addition:
2004-12-08 Shyamal Prasad <shyamal(a)member.fsf.org>
* editfns.c:
* editfns.c (Fformat_time_string):
Added documentation for %z, %g, %G and %V specifiers. This synchs
up the set of % specifiers for format-time-string with Emacs
21.3.1. Make copy of static buffer returned by localtime().
* strftime.c:
* strftime.c (strftime):
Implemented %z, %g,…
[View More] %G and %V in a style similar to existing
implementation of other specifiers.
XEmacs source patch:
Diff command: cvs -q diff -u
Files affected: src/strftime.c src/editfns.c
Index: src/editfns.c
===================================================================
RCS file: /pack/xemacscvs/XEmacs/xemacs/src/editfns.c,v
retrieving revision 1.51
diff -u -r1.51 editfns.c
--- src/editfns.c 2004/12/06 03:52:03 1.51
+++ src/editfns.c 2004/12/09 02:40:17
@@ -1015,6 +1015,8 @@
%d is replaced by the day of month, zero-padded.
%D is a synonym for "%m/%d/%y".
%e is replaced by the day of month, blank-padded.
+%G is replaced by the year containing the ISO 8601 week
+%g is replaced by the year of the ISO 8601 week within the century (00-99)
%h is a synonym for "%b".
%H is replaced by the hour (00-23).
%I is replaced by the hour (00-12).
@@ -1033,12 +1035,14 @@
%t is a synonym for "\\t".
%T is a synonym for "%H:%M:%S".
%U is replaced by the week of the year (00-53), first day of week is Sunday.
+%V is replaced by the ISO 8601 week number
%w is replaced by the day of week (0-6), Sunday is day 0.
%W is replaced by the week of the year (00-53), first day of week is Monday.
%x is a locale-specific synonym, which defaults to "%D" in the C locale.
%X is a locale-specific synonym, which defaults to "%T" in the C locale.
%y is replaced by the year without century (00-99).
%Y is replaced by the year with century.
+%z is replaced by the time zone as a numeric offset (e.g +0530, -0800 etc.)
%Z is replaced by the time zone abbreviation.
The number of options reflects the `strftime' function.
@@ -1063,13 +1067,15 @@
{
Extbyte *buf = alloca_extbytes (size);
Extbyte *formext;
+ /* make a copy of the static buffer returned by localtime() */
+ struct tm tm = * localtime(&value);
+
*buf = 1;
/* !!#### this use of external here is not totally safe, and
potentially data lossy. */
LISP_STRING_TO_EXTERNAL (format_string, formext, Qnative);
- if (emacs_strftime (buf, size, formext,
- localtime (&value))
+ if (emacs_strftime (buf, size, formext, &tm)
|| !*buf)
return build_ext_string (buf, Qnative);
/* If buffer was too small, make it bigger. */
Index: src/strftime.c
===================================================================
RCS file: /pack/xemacscvs/XEmacs/xemacs/src/strftime.c,v
retrieving revision 1.6
diff -u -r1.6 strftime.c
--- src/strftime.c 2002/03/29 04:48:37 1.6
+++ src/strftime.c 2004/12/09 02:40:18
@@ -58,6 +58,7 @@
%S second (00..61)
%T time, 24-hour (hh:mm:ss)
%X locale's time representation (%H:%M:%S)
+ %z time zone offset (e.g. +0530, -0800 etc)
%Z time zone (EDT), or nothing if no time zone is determinable
Date fields:
@@ -70,10 +71,13 @@
%d day of month (01..31)
%e day of month ( 1..31)
%D date (mm/dd/yy)
+ %G year corresponding to the ISO 8601 week
+ %g Year of the ISO 8601 week within century (00 - 99)
%h same as %b
%j day of year (001..366)
%m month (01..12)
%U week number of year with Sunday as first day of week (00..53)
+ %V ISO 8601 week number (first week is the earliest one with Thu)
%w day of week (0..6)
%W week number of year with Monday as first day of week (00..53)
%x locale's date representation (mm/dd/yy)
@@ -235,6 +239,30 @@
return dl <= 0 ? 0 : dl / 7 + (dl % 7 != 0);
}
+#ifndef __isleap
+/* Nonzero if YEAR is a leap year (every 4 years,
+ except every 100th isn't, and every 400th is). */
+# define __isleap(year) \
+ ((year) % 4 == 0 && ((year) % 100 != 0 || (year) % 400 == 0))
+#endif
+
+/* The number of days from the first day of the first ISO week of this
+ year to the year day YDAY with week day WDAY. ISO weeks start on
+ Monday; the first ISO week has the year's first Thursday. YDAY may
+ be as small as YDAY_MINIMUM. */
+#define ISO_WEEK_START_WDAY 1 /* Monday */
+#define ISO_WEEK1_WDAY 4 /* Thursday */
+#define YDAY_MINIMUM (-366)
+static int
+iso_week_days (int yday, int wday)
+{
+ /* Add enough to the first operand of % to make it nonnegative. */
+ int big_enough_multiple_of_7 = (-YDAY_MINIMUM / 7 + 2) * 7;
+ return (yday
+ - (yday - wday + ISO_WEEK1_WDAY + big_enough_multiple_of_7) % 7
+ + ISO_WEEK1_WDAY - ISO_WEEK_START_WDAY);
+}
+
#if !defined(HAVE_TM_ZONE) && !defined(HAVE_TZNAME)
char *zone_name (const struct tm *tp);
char *
@@ -362,10 +390,125 @@
length +=
strftime (&string[length], max - length, "%H:%M:%S", tm);
break;
+
+ case 'V':
+ case 'g':
+ case 'G':
+ {
+ int year = tm->tm_year + 1900;
+ int days = iso_week_days (tm->tm_yday, tm->tm_wday);
+
+ if (days < 0)
+ {
+ /* This ISO week belongs to the previous year. */
+ year--;
+ days =
+ iso_week_days (tm->tm_yday + (365 + __isleap (year)),
+ tm->tm_wday);
+ }
+ else
+ {
+ int d =
+ iso_week_days (tm->tm_yday - (365 + __isleap (year)),
+ tm->tm_wday);
+ if (0 <= d)
+ {
+ /* This ISO week belongs to the next year. */
+ year++;
+ days = d;
+ }
+ }
+
+ switch (*format)
+ {
+ /*
+ #### FIXME
+ We really can't assume 1000 <= year <= 9999
+ once time_t gets beyond 32 bits, but it's true
+ of the rest of the code here so get with the
+ program
+ */
+ case 'g':
+ length +=
+ add_num2 (&string[length], year % 100,
+ max - length, pad);
+ break;
+
+ case 'G':
+ add_char (year / 1000 + '0');
+ length += add_num3 (&string[length], year % 1000,
+ max - length, zero);
+ break;
+
+ default:
+ length +=
+ add_num2 (&string[length], days / 7 + 1,
+ max - length, pad);
+ break;
+ }
+ }
+ break;
case 'X':
length +=
strftime (&string[length], max - length, "%H:%M:%S", tm);
break;
+ case 'z':
+ {
+ /*
+ #### FIXME: could use tm->tm_gmtoff if present. Since
+ the other code in xemacs does not do so we follow the
+ leaders (and don't add a autoconf macro to detect
+ its presence).
+ */
+ long int offset;
+ long int minutes;
+ struct tm lt, *ut;
+ time_t utc;
+
+ lt = *tm;
+ utc = mktime(<);
+ ut = gmtime(&utc);
+ /* assume that tm is valid so the others will be too! */
+ assert( utc != (time_t) -1 && ut != NULL );
+
+ /* tm diff code below is based on mktime.c, glibc 2.3.2 */
+ {
+ int lt4, ut4, lt100, ut100, lt400, ut400;
+ int intervening_leap_days, years, days;
+
+ lt4 = (lt.tm_year >> 2) + (1900 >> 2) -
+ ! (lt.tm_year & 3);
+ ut4 = (ut->tm_year >> 2) + (1900 >> 2) -
+ ! (ut->tm_year & 3);
+ lt100 = lt4 / 25 - (lt4 % 25 < 0);
+ ut100 = ut4 / 25 - (ut4 % 25 < 0);
+ lt400 = lt100 >> 2;
+ ut400 = ut100 >> 2;
+ intervening_leap_days =
+ (lt4 - ut4) - (lt100 - ut100) + (lt400 - ut400);
+ years = lt.tm_year - ut->tm_year;
+ days = (365 * years + intervening_leap_days
+ + (lt.tm_yday - ut->tm_yday));
+ offset = (60 * (60 * (24 * days + (lt.tm_hour - ut->tm_hour))
+ + (lt.tm_min - ut->tm_min))
+ + (lt.tm_sec - ut->tm_sec));
+ }
+
+ minutes = offset / ( offset < 0 ? -60 : 60 );
+
+ add_char ((offset < 0 ? '-' : '+'));
+
+ if ( minutes / 600 != 0 )
+ add_char (minutes / 600 + '0');
+ else if ( pad != none )
+ add_char ((pad == zero ? '0' : ' '));
+
+ length +=
+ add_num3 (&string[length],
+ ((minutes / 60 ) % 10) * 100 + (minutes % 60),
+ max - length, pad);
+ break;
+ }
case 'Z':
#ifdef HAVE_TM_ZONE
length += add_str (&string[length], tm->tm_zone, max - length);
[View Less]
[PATCH (pkgs)] Small AUCTeX tweak
17 years, 10 months
Jerry James
PATCH packages
As David Kastrup said on xemacs-beta, using rawfile IS the right thing
to do here. I suggest this patch as a stopgap measure until we can
figure out how to import the latest version of AUCTeX.
This incidentally fixes the building of HISTORY.
xemacs-packages/auctex/ChangeLog addition:
2006-08-03 Jerry James <james(a)xemacs.org>
* Makefile (EXTRA_SOURCES): Add HISTORY.
* Makefile (RUN_MAKEINFO_INDIVIDUAL): Build plain text files with
-D rawfile.
* Makefile (…
[View More]HISTORY): Builds correctly with the previous fix.
packages source patch:
Diff command: cvs -q diff -uN
Files affected: xemacs-packages/auctex/Makefile
Index: xemacs-packages/auctex/Makefile
===================================================================
RCS file: /pack/xemacscvs/XEmacs/packages/xemacs-packages/auctex/Makefile,v
retrieving revision 1.59
diff -d -u -r1.59 Makefile
--- xemacs-packages/auctex/Makefile 2005/02/12 17:10:02 1.59
+++ xemacs-packages/auctex/Makefile 2006/08/03 20:20:04
@@ -35,7 +35,7 @@
context-en.elc context-nl.elc tex-fold.elc \
-EXTRA_SOURCES = CHANGES PROBLEMS README FAQ RELEASE TODO \
+EXTRA_SOURCES = CHANGES PROBLEMS README FAQ RELEASE TODO HISTORY \
ChangeLog.auctex tex-site.el \
ETC_ELCS = etc/units.elc etc/nicefrac.elc etc/alltt.elc \
@@ -102,7 +102,7 @@
&& texindex auc-tex.vr && texindex auc-tex.cp \
&& $(TEX) "\nonstopmode\input auc-tex.texi"
-RUN_MAKEINFO_INDIVIDUAL = $(MAKEINFO) -I texi/ --no-validate --force --no-headers -o $@ $<
+RUN_MAKEINFO_INDIVIDUAL = $(MAKEINFO) -D rawfile -I texi/ --no-validate --force --no-headers -o $@ $<
INSTALLATION: texi/install.texi
-$(RUN_MAKEINFO_INDIVIDUAL)
@@ -113,6 +113,5 @@
CHANGES: texi/changes.texi
-$(RUN_MAKEINFO_INDIVIDUAL)
-# does not build.
HISTORY: texi/history.texi
-$(RUN_MAKEINFO_INDIVIDUAL)
--
Jerry James, Assistant Professor james(a)xemacs.org
Computer Science Department http://www.cs.usu.edu/~jerry/
Utah State University
[View Less]
[PATCH 21.5] POP sync
18 years, 4 months
Jerry James
PATCH 21.5
Our current pop.c has a number of problems flagged by some static
checkers, but the Emacs version checks clean. Here's a sync so we can
be as clean as a whistle, too.
lib-src/ChangeLog addition:
2006-08-11 Jerry James <james(a)xemacs.org>
* pop.h: Sync with Emacs.
* pop.c: Ditto.
xemacs-21.5 source patch:
Diff command: cvs -q diff -uN
Files affected: lib-src/pop.c lib-src/pop.h
Index: lib-src/pop.h
==================================================================…
[View More]=
RCS file: /pack/xemacscvs/XEmacs/xemacs/lib-src/pop.h,v
retrieving revision 1.2
diff -d -u -r1.2 pop.h
--- lib-src/pop.h 2001/06/10 10:42:17 1.2
+++ lib-src/pop.h 2006/08/11 18:22:07
@@ -1,5 +1,6 @@
/* pop.h: Header file for the "pop.c" client POP3 protocol.
- Copyright (c) 1991,1993 Free Software Foundation, Inc.
+ Copyright (C) 1991, 1993, 2002, 2003, 2004,
+ 2005, 2006 Free Software Foundation, Inc.
Written by Jonathan Kamens, jik(a)security.ov.com.
This file is part of XEmacs.
@@ -16,8 +17,10 @@
You should have received a copy of the GNU General Public License
along with XEmacs; see the file COPYING. If not, write to
-the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA. */
+the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+Boston, MA 02110-1301, USA. */
+
+/* Synched up with: FSF 22.0.50. */
#include <stdio.h>
@@ -59,7 +62,8 @@
extern int pop_stat _ARGS((popserver server, int *count, int *size));
extern int pop_list _ARGS((popserver server, int message, int **IDs,
int **size));
-extern char *pop_retrieve _ARGS((popserver server, int message, int markfrom));
+extern int pop_retrieve _ARGS((popserver server, int message, int markfrom,
+ char **));
extern int pop_retrieve_first _ARGS((popserver server, int message,
char **response));
extern int pop_retrieve_next _ARGS((popserver server, char **line));
Index: lib-src/pop.c
===================================================================
RCS file: /pack/xemacscvs/XEmacs/xemacs/lib-src/pop.c,v
retrieving revision 1.10
diff -d -u -r1.10 pop.c
--- lib-src/pop.c 2004/09/20 19:19:11 1.10
+++ lib-src/pop.c 2006/08/11 18:22:07
@@ -1,5 +1,6 @@
/* pop.c: client routines for talking to a POP3-protocol post-office server
- Copyright (c) 1991, 1993, 1996 Free Software Foundation, Inc.
+ Copyright (C) 1991, 1993, 1996, 1997, 1999, 2002, 2003, 2004,
+ 2005, 2006 Free Software Foundation, Inc.
Copyright (C) 2001 Ben Wing.
Written by Jonathan Kamens, jik(a)security.ov.com.
@@ -17,8 +18,10 @@
You should have received a copy of the GNU General Public License
along with XEmacs; see the file COPYING. If not, write to
-the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA. */
+the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+Boston, MA 02110-1301, USA. */
+
+/* Synched up with: FSF 22.0.50. */
#ifdef HAVE_CONFIG_H
#define NO_SHORTNAMES /* Tell config not to load remap.h */
@@ -96,7 +99,7 @@
#ifdef KERBEROS
#ifndef KRB5
extern int krb_sendauth (/* long, int, KTEXT, char *, char *, char *,
- unsigned long, MSG_DAT *, CREDENTIALS *, Key_schedule,
+ u_long, MSG_DAT *, CREDENTIALS *, Key_schedule,
struct sockaddr_in *, struct sockaddr_in *,
char * */);
extern char *krb_realmofhost (/* char * */);
@@ -110,7 +113,7 @@
#endif
static int socket_connection (char *, int);
-static char *pop_getline (popserver);
+static int pop_getline (popserver, char **);
static int sendline (popserver, char *);
static int fullwrite (int, char *, int);
static int getok (popserver);
@@ -118,9 +121,11 @@
static int gettermination (popserver);
#endif
static void pop_trash (popserver);
-static char *find_crlf (char *);
+static char *find_crlf (char *, int);
-#define ERROR_MAX 80 /* a pretty arbitrary size */
+#define ERROR_MAX 160 /* a pretty arbitrary size, but needs
+ to be bigger than the original
+ value of 80 */
#define POP_PORT 110
#define KPOP_PORT 1109
#if defined(WIN32_NATIVE) || defined(CYGWIN)
@@ -130,7 +135,7 @@
#endif
#ifdef KERBEROS
#ifdef KRB5
-#define KPOP_SERVICE "k5pop";
+#define KPOP_SERVICE "k5pop"
#else
#define KPOP_SERVICE "kpop"
#endif
@@ -356,7 +361,7 @@
return (-1);
}
- if (sendline (server, "STAT") || (! (fromserver = pop_getline (server))))
+ if (sendline (server, "STAT") || (pop_getline (server, &fromserver) < 0))
return (-1);
if (strncmp (fromserver, "+OK ", 4))
@@ -448,7 +453,7 @@
free ((char *) *sizes);
return (-1);
}
- if (! (fromserver = pop_getline (server)))
+ if (pop_getline (server, &fromserver) < 0)
{
free ((char *) *IDs);
free ((char *) *sizes);
@@ -493,7 +498,7 @@
}
for (i = 0; i < how_many; i++)
{
- if (pop_multi_next (server, &fromserver))
+ if (pop_multi_next (server, &fromserver) <= 0)
{
free ((char *) *IDs);
free ((char *) *sizes);
@@ -512,7 +517,7 @@
}
(*sizes)[i] = atoi (fromserver);
}
- if (pop_multi_next (server, &fromserver))
+ if (pop_multi_next (server, &fromserver) < 0)
{
free ((char *) *IDs);
free ((char *) *sizes);
@@ -542,14 +547,17 @@
* markfrom
* If true, then mark the string "From " at the beginning
* of lines with '>'.
+ * msg_buf Output parameter to which a buffer containing the
+ * message is assigned.
*
- * Return value: A string pointing to the message, if successful, or
- * null with pop_error set if not.
+ * Return value: The number of bytes in msg_buf, which may contain
+ * embedded nulls, not including its final null, or -1 on error
+ * with pop_error set.
*
* Side effects: May kill connection on error.
*/
-char *
-pop_retrieve (popserver server, int message, int markfrom)
+int
+pop_retrieve (popserver server, int message, int markfrom, char **msg_buf)
{
int *IDs, *sizes, bufsize, fromcount = 0, cp = 0;
char *ptr, *fromserver;
@@ -562,11 +570,11 @@
}
if (pop_list (server, message, &IDs, &sizes))
- return (0);
+ return (-1);
if (pop_retrieve_first (server, message, &fromserver))
{
- return (0);
+ return (-1);
}
/*
@@ -584,17 +592,16 @@
{
strcpy (pop_error, "Out of memory in pop_retrieve");
pop_retrieve_flush (server);
- return (0);
+ return (-1);
}
- while (! (ret = pop_retrieve_next (server, &fromserver)))
+ while ((ret = pop_retrieve_next (server, &fromserver)) >= 0)
{
- int linesize;
-
if (! fromserver)
{
ptr[cp] = '\0';
- return (ptr);
+ *msg_buf = ptr;
+ return (cp);
}
if (markfrom && fromserver[0] == 'F' && fromserver[1] == 'r' &&
fromserver[2] == 'o' && fromserver[3] == 'm' &&
@@ -608,25 +615,19 @@
{
strcpy (pop_error, "Out of memory in pop_retrieve");
pop_retrieve_flush (server);
- return (0);
+ return (-1);
}
fromcount = 0;
}
ptr[cp++] = '>';
}
- linesize = strlen (fromserver);
- memcpy (&ptr[cp], fromserver, linesize);
- cp += linesize;
+ memcpy (&ptr[cp], fromserver, ret);
+ cp += ret;
ptr[cp++] = '\n';
}
- if (ret)
- {
- free (ptr);
- /* return (0); */
- }
- /* This function used to fall off the end, but that doesn't make any sense */
- return (0);
+ free (ptr);
+ return (-1);
}
int
@@ -636,6 +637,14 @@
return (pop_multi_first (server, pop_error, response));
}
+/*
+ Returns a negative number on error, 0 to indicate that the data has
+ all been read (i.e., the server has returned a "." termination
+ line), or a positive number indicating the number of bytes in the
+ returned buffer (which is null-terminated and may contain embedded
+ nulls, but the returned bytecount doesn't include the final null).
+ */
+
int
pop_retrieve_next (popserver server, char **line)
{
@@ -655,6 +664,14 @@
return (pop_multi_first (server, pop_error, response));
}
+/*
+ Returns a negative number on error, 0 to indicate that the data has
+ all been read (i.e., the server has returned a "." termination
+ line), or a positive number indicating the number of bytes in the
+ returned buffer (which is null-terminated and may contain embedded
+ nulls, but the returned bytecount doesn't include the final null).
+ */
+
int
pop_top_next (popserver server, char **line)
{
@@ -677,7 +694,7 @@
return (-1);
}
- if (sendline (server, command) || (! (*response = pop_getline (server))))
+ if (sendline (server, command) || (pop_getline (server, response) < 0))
{
return (-1);
}
@@ -701,10 +718,20 @@
}
}
+/*
+ Read the next line of data from SERVER and place a pointer to it
+ into LINE. Return -1 on error, 0 if there are no more lines to read
+ (i.e., the server has returned a line containing only "."), or a
+ positive number indicating the number of bytes in the LINE buffer
+ (not including the final null). The data in that buffer may contain
+ embedded nulls, but does not contain the final CRLF. When returning
+ 0, LINE is set to null. */
+
int
pop_multi_next (popserver server, char **line)
{
char *fromserver;
+ int ret;
if (! server->in_multi)
{
@@ -712,8 +739,7 @@
return (-1);
}
- fromserver = pop_getline (server);
- if (! fromserver)
+ if ((ret = pop_getline (server, &fromserver)) < 0)
{
return (-1);
}
@@ -729,13 +755,13 @@
else
{
*line = fromserver + 1;
- return (0);
+ return (ret - 1);
}
}
else
{
*line = fromserver;
- return (0);
+ return (ret);
}
}
@@ -743,21 +769,22 @@
pop_multi_flush (popserver server)
{
char *line;
+ int ret;
if (! server->in_multi)
{
return (0);
}
- while (! pop_multi_next (server, &line))
+ while ((ret = pop_multi_next (server, &line)))
{
- if (! line)
+ if (ret < 0)
{
- return (0);
+ return (-1);
}
}
- return (-1);
+ return (0);
}
/* Function: pop_delete
@@ -844,7 +871,7 @@
if (sendline (server, "LAST"))
return (-1);
- if (! (fromserver = pop_getline (server)))
+ if (pop_getline (server, &fromserver) < 0)
return (-1);
if (! strncmp (fromserver, "-ERR", 4))
@@ -968,6 +995,8 @@
#ifdef KERBEROS
#ifdef KRB5
krb5_error_code rem;
+ krb5_context kcontext = 0;
+ krb5_auth_context auth_context = 0;
krb5_ccache ccdef;
krb5_principal client, server;
krb5_error *err_ret;
@@ -978,6 +1007,7 @@
CREDENTIALS cred;
Key_schedule schedule;
int rem;
+ char *realhost;
#endif /* KRB5 */
#endif /* KERBEROS */
@@ -991,19 +1021,6 @@
}
#endif
- do
- {
- hostent = gethostbyname (host);
- try_count++;
- if ((! hostent)
- && ((h_errno != TRY_AGAIN) || (try_count == 5))
- )
- {
- strcpy (pop_error, "Could not determine POP server's address");
- return (-1);
- }
- } while (! hostent);
-
memset (&addr, 0, sizeof (addr));
addr.sin_family = AF_INET;
@@ -1042,18 +1059,29 @@
}
}
-#define SOCKET_ERROR "Could not create socket for POP connection: "
+#define POP_SOCKET_ERROR "Could not create socket for POP connection: "
sock = socket (PF_INET, SOCK_STREAM, 0);
if (sock < 0)
{
- strcpy (pop_error, SOCKET_ERROR);
+ strcpy (pop_error, POP_SOCKET_ERROR);
strncat (pop_error, strerror (errno),
- ERROR_MAX - sizeof (SOCKET_ERROR));
+ ERROR_MAX - sizeof (POP_SOCKET_ERROR));
return (-1);
}
+ do
+ {
+ hostent = gethostbyname (host);
+ try_count++;
+ if ((! hostent) && ((h_errno != TRY_AGAIN) || (try_count == 5)))
+ {
+ strcpy (pop_error, "Could not determine POP server's address");
+ return (-1);
+ }
+ } while (! hostent);
+
while (*hostent->h_addr_list)
{
memcpy (&addr.sin_addr, *hostent->h_addr_list, hostent->h_length);
@@ -1079,11 +1107,13 @@
if (! (flags & POP_NO_KERBEROS))
{
#ifdef KRB5
- krb5_init_ets ();
-
- if (rem = krb5_cc_default (&ccdef))
+ if ((rem = krb5_init_context (&kcontext)))
{
krb5error:
+ if (auth_context)
+ krb5_auth_con_free (kcontext, auth_context);
+ if (kcontext)
+ krb5_free_context (kcontext);
strcpy (pop_error, KRB_ERROR);
strncat (pop_error, error_message (rem),
ERROR_MAX - sizeof(KRB_ERROR));
@@ -1091,11 +1121,15 @@
return (-1);
}
- if (rem = krb5_cc_get_principal (ccdef, &client))
- {
- goto krb5error;
- }
+ if ((rem = krb5_auth_con_init (kcontext, &auth_context)))
+ goto krb5error;
+ if (rem = krb5_cc_default (kcontext, &ccdef))
+ goto krb5error;
+
+ if (rem = krb5_cc_get_principal (kcontext, ccdef, &client))
+ goto krb5error;
+
for (cp = hostent->h_name; *cp; cp++)
{
if (isupper (*cp))
@@ -1104,22 +1138,20 @@
}
}
- if (rem = krb5_sname_to_principal (hostent->h_name, POP_SERVICE,
- FALSE, &server))
- {
- goto krb5error;
- }
+ if (rem = krb5_sname_to_principal (kcontext, hostent->h_name,
+ POP_SERVICE, FALSE, &server))
+ goto krb5error;
- rem = krb5_sendauth ((krb5_pointer) &sock, "KPOPV1.0", client, server,
+ rem = krb5_sendauth (kcontext, &auth_context,
+ (krb5_pointer) &sock, "KPOPV1.0", client, server,
AP_OPTS_MUTUAL_REQUIRED,
0, /* no checksum */
0, /* no creds, use ccache instead */
ccdef,
- 0, /* don't need seq # */
- 0, /* don't need subsession key */
&err_ret,
+ 0, /* don't need subsession key */
0); /* don't need reply */
- krb5_free_principal (server);
+ krb5_free_principal (kcontext, server);
if (rem)
{
if (err_ret && err_ret->text.length)
@@ -1142,20 +1174,23 @@
ERROR_MAX - sizeof (KRB_ERROR));
}
if (err_ret)
- krb5_free_error (err_ret);
+ krb5_free_error (kcontext, err_ret);
+ krb5_auth_con_free (kcontext, auth_context);
+ krb5_free_context (kcontext);
CLOSESOCKET (sock);
return (-1);
}
#else /* ! KRB5 */
ticket = (KTEXT) malloc (sizeof (KTEXT_ST));
- rem = krb_sendauth (0L, sock, ticket, "pop", hostent->h_name,
- (char *) krb_realmofhost (hostent->h_name),
+ rem = krb_sendauth (0L, sock, ticket, "pop", realhost,
+ (char *) krb_realmofhost (realhost),
(unsigned long) 0, &msg_data, &cred, schedule,
(struct sockaddr_in *) 0,
(struct sockaddr_in *) 0,
"KPOPV0.1");
free ((char *) ticket);
+ free (realhost);
if (rem != KSUCCESS)
{
strcpy (pop_error, KRB_ERROR);
@@ -1182,15 +1217,20 @@
* Arguments:
* server The server from which to get the line of text.
*
- * Returns: A non-null pointer if successful, or a null pointer on any
- * error, with an error message copied into pop_error.
+ * Returns: The number of characters in the line, which is returned in
+ * LINE, not including the final null. A return value of 0
+ * indicates a blank line. A negative return value indicates an
+ * error (in which case the contents of LINE are undefined. In
+ * case of error, an error message is copied into pop_error.
*
* Notes: The line returned is overwritten with each call to pop_getline.
*
* Side effects: Closes the connection on error.
+ *
+ * THE RETURNED LINE MAY CONTAIN EMBEDDED NULLS!
*/
-static char *
-pop_getline (popserver server)
+static int
+pop_getline (popserver server, char **line)
{
#define GETLINE_ERROR "Error reading from server: "
@@ -1199,7 +1239,8 @@
if (server->data)
{
- char *cp = find_crlf (server->buffer + server->buffer_index);
+ char *cp = find_crlf (server->buffer + server->buffer_index,
+ server->data);
if (cp)
{
int found;
@@ -1213,8 +1254,11 @@
server->buffer_index += data_used;
if (pop_debug)
+ /* Embedded nulls will truncate this output prematurely,
+ but that's OK because it's just for debugging anyway. */
fprintf (stderr, "<<< %s\n", server->buffer + found);
- return (server->buffer + found);
+ *line = server->buffer + found;
+ return (data_used - 2);
}
else
{
@@ -1250,7 +1294,7 @@
{
strcpy (pop_error, "Out of memory in pop_getline");
pop_trash (server);
- return (0);
+ return (-1);
}
}
ret = RECV (server->file, server->buffer + server->data,
@@ -1261,13 +1305,13 @@
strncat (pop_error, strerror (errno),
ERROR_MAX - sizeof (GETLINE_ERROR));
pop_trash (server);
- return (0);
+ return (-1);
}
else if (ret == 0)
{
strcpy (pop_error, "Unexpected EOF from server in pop_getline");
pop_trash (server);
- return (0);
+ return (-1);
}
else
{
@@ -1275,7 +1319,8 @@
server->data += ret;
server->buffer[server->data] = '\0';
- cp = find_crlf (server->buffer + search_offset);
+ cp = find_crlf (server->buffer + search_offset,
+ server->data - search_offset);
if (cp)
{
int data_used = (cp + 2) - server->buffer;
@@ -1285,9 +1330,12 @@
if (pop_debug)
fprintf (stderr, "<<< %s\n", server->buffer);
- return (server->buffer);
+ *line = server->buffer;
+ return (data_used - 2);
}
- search_offset += ret;
+ /* As above, the "- 1" here is to account for the fact that
+ we may have read a CR without its accompanying LF. */
+ search_offset += ret - 1;
}
}
@@ -1317,12 +1365,24 @@
{
#define SENDLINE_ERROR "Error writing to POP server: "
int ret;
+ char *buf;
+
+ /* Combine the string and the CR-LF into one buffer. Otherwise, two
+ reasonable network stack optimizations, Nagle's algorithm and
+ delayed acks, combine to delay us a fraction of a second on every
+ message we send. (Movemail writes line without \r\n, client
+ kernel sends packet, server kernel delays the ack to see if it
+ can combine it with data, movemail writes \r\n, client kernel
+ waits because it has unacked data already in its outgoing queue,
+ client kernel eventually times out and sends.)
+ This can be something like 0.2s per command, which can add up
+ over a few dozen messages, and is a big chunk of the time we
+ spend fetching mail from a server close by. */
+ buf = alloca (strlen (line) + 3);
+ strcpy (buf, line);
+ strcat (buf, "\r\n");
ret = fullwrite (server->file, line, strlen (line));
- if (ret >= 0)
- { /* 0 indicates that a blank line was written */
- ret = fullwrite (server->file, "\r\n", 2);
- }
if (ret < 0)
{
@@ -1351,10 +1411,10 @@
fullwrite (int fd, char *buf, int nbytes)
{
char *cp;
- int ret;
+ int ret = 0;
cp = buf;
- while ((ret = SEND (fd, cp, nbytes, 0)) > 0)
+ while (nbytes && ((ret = SEND (fd, cp, nbytes, 0)) > 0))
{
cp += ret;
nbytes -= ret;
@@ -1382,7 +1442,7 @@
{
char *fromline;
- if (! (fromline = pop_getline (server)))
+ if (pop_getline (server, &fromline) < 0)
{
return (-1);
}
@@ -1420,8 +1480,7 @@
{
char *fromserver;
- fromserver = pop_getline (server);
- if (! fromserver)
+ if (pop_getline (server, &fromserver) < 0)
return (-1);
if (strcmp (fromserver, "."))
@@ -1492,17 +1551,16 @@
#endif
}
-/* Return a pointer to the first CRLF in IN_STRING,
- or 0 if it does not contain one. */
+/* Return a pointer to the first CRLF in IN_STRING, which can contain
+ embedded nulls and has LEN characters in it not including the final
+ null, or 0 if it does not contain one. */
static char *
-find_crlf (char *in_string)
+find_crlf (char *in_string, int len)
{
- while (1)
+ while (len--)
{
- if (! *in_string)
- return (0);
- else if (*in_string == '\r')
+ if (*in_string == '\r')
{
if (*++in_string == '\n')
return (in_string - 1);
@@ -1510,7 +1568,7 @@
else
in_string++;
}
- /* NOTREACHED */
+ return (0);
}
#endif /* MAIL_USE_POP */
--
Jerry James, Assistant Professor james(a)xemacs.org
Computer Science Department http://www.cs.usu.edu/~jerry/
Utah State University
[View Less]
[PATCH 21.5] gnuclient buffer overflow fixes
18 years, 4 months
Jerry James
PATCH 21.5
The gnuclient.c part of this patch will not apply to 21.4. I can make a
new patch for 21.4 if desired, though. Here are fixes for a few, um,
undesirable features found with a static checker.
lib-src/ChangeLog addition:
2006-08-08 Jerry James <james(a)xemacs.org>
* gnuslib.c (disconnect_from_server): shutdown() has been fine on
Linux for a long time now; use it. Also, don't use length to
access the buffer unless it is positive, not just nonzero.
* gnuclient.c (…
[View More]filename_expand): Initialize the last array element
to get a valid C string in case of overflow. Use strncat to avoid
buffer overruns.
* gnuclient.c (main): Use strncpy to avoid buffer overruns.
xemacs-21.5 source patch:
Diff command: cvs -q diff -uN
Files affected: lib-src/gnuclient.c
===================================================================
RCS lib-src/gnuslib.c
===================================================================
RCS
Index: lib-src/gnuslib.c
===================================================================
RCS file: /pack/xemacscvs/XEmacs/xemacs/lib-src/gnuslib.c,v
retrieving revision 1.12
diff -d -u -r1.12 gnuslib.c
--- lib-src/gnuslib.c 2001/08/13 04:45:48 1.12
+++ lib-src/gnuslib.c 2006/08/08 20:27:59
@@ -409,13 +409,11 @@
send_string(s,EOT_STR); /* make sure server gets string */
-#if !defined (linux) && !defined (_SCO_DS)
+#ifndef _SCO_DS
/*
- * shutdown is completely hozed under linux. If s is a unix domain socket,
- * you'll get EOPNOTSUPP back from it. If s is an internet socket, you get
- * a broken pipe when you try to read a bit later. The latter
- * problem is fixed for linux versions >= 1.1.46, but the problem
- * with unix sockets persists. Sigh.
+ * There used to be a comment here complaining about ancient Linux
+ * versions. It is no longer relevant. I don't know why _SCO_DS is
+ * verboten here, as the original comment did not say.
*/
if (shutdown(s,1) == -1) {
@@ -434,7 +432,7 @@
#else
while ((length = read(s,buffer,GSERV_BUFSZ)) > 0 ||
(length == -1 && errno == EINTR)) {
- if (length) {
+ if (length > 0) {
buffer[length] = '\0';
if (echo) {
fputs(buffer,stdout);
Index: lib-src/gnuclient.c
===================================================================
RCS file: /pack/xemacscvs/XEmacs/xemacs/lib-src/gnuclient.c,v
retrieving revision 1.27
diff -d -u -r1.27 gnuclient.c
--- lib-src/gnuclient.c 2004/12/06 23:23:41 1.27
+++ lib-src/gnuclient.c 2006/08/08 20:27:59
@@ -187,7 +187,7 @@
#endif
int len;
- fullpath[0] = '\0';
+ fullpath[0] = fullpath[QXE_PATH_MAX] = '\0';
#ifdef CYGWIN
/*
@@ -200,7 +200,7 @@
if (filename[0] && filename[0] == '/')
{
/* Absolute (unix-style) pathname. Do nothing */
- strcat (fullpath, filename);
+ strncat (fullpath, filename, QXE_PATH_MAX);
}
else
{
@@ -208,15 +208,18 @@
and prepend it. FIXME: need to fix the case of DOS paths like
"\foo", where we need to get the current drive. */
- strcat (fullpath, get_current_working_directory ());
+ strncat (fullpath, get_current_working_directory (), QXE_PATH_MAX);
len = strlen (fullpath);
- if (len > 0 && fullpath[len-1] == '/') /* trailing slash already? */
- ; /* yep */
- else
- strcat (fullpath, "/"); /* nope, append trailing slash */
+ /* If no trailing slash, add one */
+ if (len <= 0 || (fullpath[len - 1] != '/' && len < QXE_PATH_MAX))
+ {
+ strcat (fullpath, "/");
+ len++;
+ }
+
/* Don't forget to add the filename! */
- strcat (fullpath,filename);
+ strncat (fullpath, filename, QXE_PATH_MAX - len);
}
} /* filename_expand */
@@ -435,7 +438,7 @@
break;
case 'r':
GET_ARGUMENT (remotearg, "-r");
- strcpy (remotepath, remotearg);
+ strncpy (remotepath, remotearg, QXE_PATH_MAX);
rflg = 1;
break;
#endif /* INTERNET_DOMAIN_SOCKETS */
@@ -590,7 +593,7 @@
* to this machine */
if ((ptr = getenv ("GNU_NODE")) != NULL)
/* user specified a path */
- strcpy (remotepath, ptr);
+ strncpy (remotepath, ptr, QXE_PATH_MAX);
}
#if 0 /* This is really bogus... re-enable it if you must have it! */
#if defined (hp9000s300) || defined (hp9000s800)
--
Jerry James, Assistant Professor james(a)xemacs.org
Computer Science Department http://www.cs.usu.edu/~jerry/
Utah State University
[View Less]