Newsgroups: news.software.b
Path: utzoo!utstat!geoff
From: ge...@utstat.uucp (Geoff Collyer)
Subject: C News Bulletin #7 - rnews: 4.2bsd memcpy bug, sys F flag default
Message-ID: <1988Feb27.055152.15931@utstat.uucp>
Organization: Statistics, U. of Toronto
Date: Sat, 27 Feb 88 05:51:52 GMT
In the alpha release, rnews/vers/bsd42/memcpy.c doesn't return a value.
This does matter if, for example, you compile relaynews on a SysV/4.2
hybrid Unix in which C library functions call memcpy, such as Sunix on
the Sun 4 (a nice fast machine: 1Mb of news processed in 63 elapsed
seconds and 12 CPU seconds, using Sun's stdio; thanks to David Trueman
of Dalhousie U. for donating some Sun 4 time). Here is a replacement
memcpy():
---
char *
memcpy(to, from, length)
char *to, *from;
int length;
{
bcopy(from, to, length);
return to;
}
---
In rnews/sys.c, there is exactly one line containing
libfile(deffile)
If you change this expression to
strsave(libfile(deffile))
then you can leave the fourth field of a sys file entry containing the F
or f flags empty, and relaynews will fill in a default value
($NEWSCTL/batch/b.system/togo, where system is the first field of the
same entry).
--
Geoff Collyer utzoo!utstat!geoff, utstat.toronto.{edu,cdn}!geoff
Mr. Collyer is the senior author of C news. Latest achievement:
making the V9 shell use malloc instead of sbrk and SIGSEGV.
Newsgroups: news.software.b,comp.sources.bugs
Path: utzoo!utstat!geoff
From: ge...@utstat.uucp (Geoff Collyer)
Subject: C News Bulletin #8 - fixes for illegal message-IDs, System V ln(1)
Message-ID: <1988Oct18.064611.25833@utstat.uucp>
Organization: Statistics, U. of Toronto
Date: Tue, 18 Oct 88 06:46:11 GMT
C News Alpha rnews turns newlines and tabs in Message-IDs into spaces
when writing the history file, which keeps the history file format sane,
but not when looking up Message-IDs. Here is the current getposhist()
from rnews/history.c, retrofitted to the alpha release and not tested.
The history file rebuilder needs to sanitise Message-IDs too.
static datum
getposhist(msgid) /* return seek offset of history entry */
char *msgid;
{
register char *clnmsgid;
register char *lcmsgid;
datum msgidkey, keypos;
msgidkey.dptr = NULL;
msgidkey.dsize = 0;
if (openhist()&ST_DROPPED)
return msgidkey; /* no data base */
/* dirty trick (part 1 of 2): convert copy of msgid to lower case */
lcmsgid = strsave(msgid);
strlower(lcmsgid);
clnmsgid = strsave(lcmsgid);
sanitise(clnmsgid);
msgidkey.dptr = clnmsgid;
msgidkey.dsize = strlen(clnmsgid) + 1; /* include NUL */
keypos = fetch(msgidkey); /* offset into ascii file */
free(clnmsgid);
free(lcmsgid);
return keypos;
}
Henry and I try to keep track of differences between the major Unix
variants, but as we have no pure System V's (on 3b's) handy this one
slipped past both of us: "ln old new" will unlink "new" if it exists
before making the link, on System V. We have written many shell
scripts, some of them in C News Alpha (notably newsrun), which use ln
for locking, assuming that "ln old new" will fail and return bad exit
status if "new" exists, just like link(2). ln has worked this way since
V6, in the non-USG world. Thanks to Chris Siebenmann for spotting the
change in ln's behaviour.
For now, here is an ln command that works the way we expect. System V C
News administrators will want to invoke this version of ln instead of
/bin/ln in all C news shell scripts.
/*
* ln - link old name to new name; never unlink new name.
*
* This ln should be used instead of the System V ln, because the System V
* ln erroneously unlinks the new name, and is thus useless for locking,
* in addition to being an unintuitive shock.
*
* Geoff Collyer
*/
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#define YES 1
#define NO 0
#define MAXSTR 1024
#define STREQ(a, b) (*(a) == *(b) && strcmp((a), (b)) == 0)
char *progname;
int debug;
/* forwards */
extern char *basename();
/*
* main - parse arguments and handle options
*/
main(argc, argv)
int argc;
char *argv[];
{
int c, errflg = 0, exitstat;
extern int optind;
extern char *optarg;
extern FILE *efopen();
progname = argv[0];
while ((c = getopt(argc, argv, "")) != EOF)
switch (c) {
default:
errflg++;
break;
}
if (optind >= argc || errflg) {
(void) fprintf(stderr, "usage: %s file... [directory]\n", progname);
exit(2);
}
exitstat = 0;
if (optind == argc - 1) {
if (lnktodir(argv[optind], ".") < 0)
exitstat = 1;
} else if (!isdir(argv[argc-1]) && optind == argc - 2) {
if (lnktofile(argv[optind], argv[optind+1]) < 0)
exitstat = 1;
} else
for (; optind < argc-1; optind++)
if (lnktodir(argv[optind], argv[argc-1]) < 0)
exitstat = 1;
exit(exitstat);
}
int
isdir(file) /* file is a directory? */
char *file;
{
struct stat sb;
return stat(file, &sb) >= 0 && (sb.st_mode&S_IFMT) == S_IFDIR;
}
int
lnktofile(old, new) /* link plain file old to new name */
char *old, *new;
{
int status;
if (bouncedir(old))
return -1;
status = link(old, new);
if (status < 0)
diagnose(old, (char *)NULL, new);
return status;
}
int
lnktodir(file, dir) /* link plain file into directory dir */
char *file, *dir;
{
int status;
char newname[MAXSTR];
if (bouncedir(file))
return -1;
if (!isdir(dir)) {
(void) fprintf(stderr, "%s: %s is not a directory\n",
progname, dir);
return -1;
}
(void) strcpy(newname, dir);
(void) strcat(newname, "/");
(void) strcat(newname, basename(file));
status = link(file, newname);
if (status < 0)
diagnose(file, dir, newname);
return status;
}
int
bouncedir(file)
char *file;
{
if (isdir(file)) {
(void) fprintf(stderr, "%s: may not make links to directory %s\n",
progname, file);
return YES;
} else
return NO;
}
diagnose(old, newdir, newname)
char *old, *newdir, *newname;
{
extern int errno;
int linkerrno = errno;
struct stat sb;
if (stat(old, &sb) < 0)
warning("%s does not exist", old);
else if (newdir != NULL && stat(newdir, &sb) < 0)
warning("%s does not exist", newdir);
else if (stat(newname, &sb) >= 0)
warning("%s exists", newname);
else {
errno = linkerrno;
warn2("can't link %s to %s", old, newname);
}
}
static
warn2(fmt, s1, s2)
char *fmt, *s1, *s2;
{
char warnstr[MAXSTR];
(void) sprintf(warnstr, fmt, s1, s2);
warning(warnstr, "");
}
char *
basename(file)
char *file;
{
register char *basefile = rindex(file, '/');
if (basefile == NULL)
basefile = file;
else
basefile++;
return basefile;
}
--
Geoff Collyer utzoo!utstat!geoff, utstat.toronto.edu!geoff
|