1297 lines
46 KiB
Plaintext
1297 lines
46 KiB
Plaintext
From: Digestifier <Linux-Development-Request@senator-bedfellow.mit.edu>
|
|
To: Linux-Development@senator-bedfellow.mit.edu
|
|
Reply-To: Linux-Development@senator-bedfellow.mit.edu
|
|
Date: Sat, 26 Feb 94 18:13:07 EST
|
|
Subject: Linux-Development Digest #503
|
|
|
|
Linux-Development Digest #503, Volume #1 Sat, 26 Feb 94 18:13:07 EST
|
|
|
|
Contents:
|
|
Alpha release of message catalog commands and functions (John F. Haugh II)
|
|
|
|
----------------------------------------------------------------------------
|
|
|
|
From: jfh@rpp386.cactus.org (John F. Haugh II)
|
|
Subject: Alpha release of message catalog commands and functions
|
|
Date: Sat, 26 Feb 1994 05:27:16 GMT
|
|
|
|
I've been wanting to add National Language Support to Shadow for some
|
|
time now but there is no freely redistributable NLS package that I am
|
|
aware of. I found some stuff in an old hacked up ELM directory, but
|
|
it didn't look to be complete. This isn't what I'd call "complete",
|
|
but it's better than anything I've found. And it includes a sample
|
|
message catalog for the three commands that are included.
|
|
--
|
|
#!/bin/sh
|
|
# shar: Shell Archiver (v1.29)
|
|
#
|
|
# Run the following text with /bin/sh to create:
|
|
# LICENSE
|
|
# Makefile
|
|
# patchlevel.h
|
|
# gencat.c
|
|
# gencat.msg.En_US
|
|
# catgets.c
|
|
# l_catclose.c
|
|
# l_catgets.c
|
|
# l_catopen.c
|
|
# nl_types.h
|
|
#
|
|
sed 's/^X//' << 'SHAR_EOF' > LICENSE &&
|
|
X(*
|
|
XThis document is freely plagiarised from the 'Artistic Licence',
|
|
Xdistributed as part of the Perl v4.0 kit by Larry Wall, which is
|
|
Xavailable from most major archive sites. I stole it from CrackLib.
|
|
X
|
|
X @(#)LICENSE 3.1 20:07:28 02 Feb 1994
|
|
X*)
|
|
X
|
|
XThis documents purpose is to state the conditions under which this
|
|
XPackage (See definition below) viz: "NLS-LIB", the National Language
|
|
XLibrary which is held in John Frederick Haugh, II, may be copied, such
|
|
Xthat the copyright holder maintains some semblance of artistic control
|
|
Xover the development of the package, while giving the users of the
|
|
Xpackage the right to use and distribute the Package in a more-or-less
|
|
Xcustomary fashion, plus the right to make reasonable modifications.
|
|
X
|
|
XSo there.
|
|
X
|
|
X***************************************************************************
|
|
X
|
|
XDefinitions:
|
|
X
|
|
X
|
|
XA "Package" refers to the collection of files distributed by the
|
|
XCopyright Holder, and derivatives of that collection of files created
|
|
Xthrough textual modification, or segments thereof.
|
|
X
|
|
X"Standard Version" refers to such a Package if it has not been modified,
|
|
Xor has been modified in accordance with the wishes of the Copyright
|
|
XHolder.
|
|
X
|
|
X"Copyright Holder" is whoever is named in the copyright or copyrights
|
|
Xfor the package.
|
|
X
|
|
X"You" is you, if you're thinking about copying or distributing this
|
|
XPackage.
|
|
X
|
|
X"Reasonable copying fee" is whatever you can justify on the basis of
|
|
Xmedia cost, duplication charges, time of people involved, and so on.
|
|
X(You will not be required to justify it to the Copyright Holder, but
|
|
Xonly to the computing community at large as a market that must bear the
|
|
Xfee.)
|
|
X
|
|
X"Freely Available" means that no fee is charged for the item itself,
|
|
Xthough there may be fees involved in handling the item. It also means
|
|
Xthat recipients of the item may redistribute it under the same
|
|
Xconditions they received it.
|
|
X
|
|
X
|
|
X1. You may make and give away verbatim copies of the source form of the
|
|
XStandard Version of this Package without restriction, provided that you
|
|
Xduplicate all of the original copyright notices and associated
|
|
Xdisclaimers.
|
|
X
|
|
X2. You may apply bug fixes, portability fixes and other modifications
|
|
Xderived from the Public Domain or from the Copyright Holder. A Package
|
|
Xmodified in such a way shall still be considered the Standard Version.
|
|
X
|
|
X3. You may otherwise modify your copy of this Package in any way,
|
|
Xprovided that you insert a prominent notice in each changed file stating
|
|
Xhow and when AND WHY you changed that file, and provided that you do at
|
|
Xleast ONE of the following:
|
|
X
|
|
Xa) place your modifications in the Public Domain or otherwise make them
|
|
XFreely Available, such as by posting said modifications to Usenet or an
|
|
Xequivalent medium, or placing the modifications on a major archive site
|
|
Xsuch as uunet.uu.net, or by allowing the Copyright Holder to include
|
|
Xyour modifications in the Standard Version of the Package.
|
|
X
|
|
Xb) use the modified Package only within your corporation or organization.
|
|
X
|
|
Xc) rename any non-standard executables so the names do not conflict with
|
|
Xstandard executables, which must also be provided, and provide separate
|
|
Xdocumentation for each non-standard executable that clearly documents
|
|
Xhow it differs from the Standard Version.
|
|
X
|
|
Xd) make other distribution arrangements with the Copyright Holder.
|
|
X
|
|
X4. You may distribute the programs of this Package in object code or
|
|
Xexecutable form, provided that you do at least ONE of the following:
|
|
X
|
|
Xa) distribute a Standard Version of the executables and library files,
|
|
Xtogether with instructions (in the manual page or equivalent) on where
|
|
Xto get the Standard Version.
|
|
X
|
|
Xb) accompany the distribution with the machine-readable source of the
|
|
XPackage with your modifications.
|
|
X
|
|
Xc) accompany any non-standard executables with their corresponding
|
|
XStandard Version executables, giving the non-standard executables
|
|
Xnon-standard names, and clearly documenting the differences in manual
|
|
Xpages (or equivalent), together with instructions on where to get the
|
|
XStandard Version.
|
|
X
|
|
Xd) make other distribution arrangements with the Copyright Holder.
|
|
X
|
|
X5. You may charge a reasonable copying fee for any distribution of this
|
|
XPackage. You may charge any fee you choose for support of this Package.
|
|
XYOU MAY NOT CHARGE A FEE FOR THIS PACKAGE ITSELF. However, you may
|
|
Xdistribute this Package in aggregate with other (possibly commercial)
|
|
Xprograms as part of a larger (possibly commercial) software distribution
|
|
Xprovided that YOU DO NOT ADVERTISE this package as a product of your
|
|
Xown.
|
|
X
|
|
X6. The name of the Copyright Holder may not be used to endorse or
|
|
Xpromote products derived from this software without specific prior
|
|
Xwritten permission.
|
|
X
|
|
X7. THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED
|
|
XWARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
|
|
XMERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
|
X
|
|
X The End
|
|
SHAR_EOF
|
|
chmod 0644 LICENSE || echo "restore of LICENSE fails"
|
|
sed 's/^X//' << 'SHAR_EOF' > Makefile &&
|
|
X#
|
|
X# Copyright 1994, John F. Haugh II
|
|
X# An unpublished work.
|
|
X# All rights reserved.
|
|
X#
|
|
X# Permission is granted to copy and create derivative works for any
|
|
X# non-commercial purpose, provided this copyright notice is preserved
|
|
X# in all copies of source code, or included in human readable form
|
|
X# and conspicuously displayed on all copies of object code or
|
|
X# distribution media.
|
|
X#
|
|
X# This software is provided on an AS-IS basis and the author makes
|
|
X# no warrantee of any kind. The "Artistic License" located in the
|
|
X# file LICENSE contains complete licensing information.
|
|
X#
|
|
X# %W% %U% %G%
|
|
X
|
|
XDEBUG = -g
|
|
XOPTIM = -O
|
|
XCFLAGS = $(DEBUG) $(OPTIM)
|
|
XRANLIB = echo
|
|
X
|
|
XLANG = En_US
|
|
X
|
|
XFILES = LICENSE Makefile patchlevel.h \
|
|
X gencat.c gencat.msg.En_US catgets.c \
|
|
X l_catclose.c l_catgets.c l_catopen.c nl_types.h
|
|
X
|
|
Xall: gencat catgets dspcat libnls.a gencat.cat
|
|
X
|
|
Xgencat: gencat.o libnls.a
|
|
X cc $(DEBUG) -o gencat gencat.o libnls.a
|
|
X
|
|
Xcatgets: catgets.o libnls.a
|
|
X cc $(DEBUG) -o catgets catgets.o libnls.a
|
|
X
|
|
Xdspcat: dspcat.o libnls.a
|
|
X cc $(DEBUG) -o dspcat dspcat.o libnls.a
|
|
X
|
|
Xgencat.cat: gencat.msg.$(LANG)
|
|
X ./gencat gencat.cat gencat.msg.$(LANG)
|
|
X
|
|
Xlibnls.a(l_catclose.o): l_catclose.c nl_types.h
|
|
Xlibnls.a(l_catopen.o): l_catopen.c nl_types.h
|
|
Xlibnls.a(l_catgets.o): l_catgets.c nl_types.h
|
|
X
|
|
Xlibnls.a: \
|
|
X libnls.a(l_catclose.o) \
|
|
X libnls.a(l_catgets.o) \
|
|
X libnls.a(l_catopen.o)
|
|
X $(RANLIB) libnls.a
|
|
X
|
|
Xclean:
|
|
X rm -f *.o a.out core
|
|
X
|
|
Xclobber: clean
|
|
X rm -f catgets gencat libnls.a gencat.cat
|
|
X
|
|
Xshar: libnls.shar
|
|
X
|
|
Xlibnls.shar: $(FILES)
|
|
X shar $(SHARFLAGS) $(FILES) > libnls.shar
|
|
SHAR_EOF
|
|
chmod 0644 Makefile || echo "restore of Makefile fails"
|
|
sed 's/^X//' << 'SHAR_EOF' > patchlevel.h &&
|
|
X/*
|
|
X * Copyright 1994, John F. Haugh II
|
|
X * An unpublished work.
|
|
X * All rights reserved.
|
|
X *
|
|
X * Permission is granted to copy and create derivative works for any
|
|
X * non-commercial purpose, provided this copyright notice is preserved
|
|
X * in all copies of source code, or included in human readable form
|
|
X * and conspicuously displayed on all copies of object code or
|
|
X * distribution media.
|
|
X *
|
|
X * This software is provided on an AS-IS basis and the author makes
|
|
X * no warrantee of any kind. The "Artistic License" located in the
|
|
X * file LICENSE contains complete licensing information.
|
|
X *
|
|
X * %W% %U% %G%
|
|
X */
|
|
X
|
|
X#define RELEASE 1
|
|
X#define PATCHLEVEL 0
|
|
X#define VERSION "1.0.0"
|
|
SHAR_EOF
|
|
chmod 0644 patchlevel.h || echo "restore of patchlevel.h fails"
|
|
sed 's/^X//' << 'SHAR_EOF' > gencat.c &&
|
|
X/*
|
|
X * Copyright 1994, John F. Haugh II
|
|
X * All rights reserved.
|
|
X *
|
|
X * Permission is granted to copy and create derivative works for any
|
|
X * non-commercial purpose, provided this copyright notice is preserved
|
|
X * in all copies of source code, or included in human readable form
|
|
X * and conspicuously displayed on all copies of object code or
|
|
X * distribution media.
|
|
X *
|
|
X * This software is provided on an AS-IS basis and the author makes
|
|
X * no warrantee of any kind. The "Artistic License" located in the
|
|
X * file LICENSE contains complete licensing information.
|
|
X */
|
|
X
|
|
X#ifndef lint
|
|
Xstatic char sccsid[] = "%W% %U% %G%";
|
|
X#endif
|
|
X
|
|
X#include <sys/types.h>
|
|
X#include <stdlib.h>
|
|
X#include <unistd.h>
|
|
X#include <stdio.h>
|
|
X#include <ctype.h>
|
|
X#include <string.h>
|
|
X
|
|
X#include "nl_types.h"
|
|
X
|
|
Xnl_catd catd;
|
|
X#define M(msg,def) catgets (catd, 1, msg, def)
|
|
X
|
|
Xint lineno;
|
|
Xint quotec;
|
|
X
|
|
Xchar **messages[NL_SETMAX];
|
|
X
|
|
Xvoid
|
|
Xinvalid (FILE * fp)
|
|
X{
|
|
X int c;
|
|
X
|
|
X fprintf (stderr, M(3, "invalid input line %d\n"), lineno);
|
|
X
|
|
X while ((c = getc (fp)) != '\n' && c != EOF)
|
|
X ;
|
|
X}
|
|
X
|
|
Xint
|
|
Xoctal (FILE * fp)
|
|
X{
|
|
X int c;
|
|
X int c1, c2, c3;
|
|
X
|
|
X c1 = getc (fp);
|
|
X c2 = getc (fp);
|
|
X c3 = getc (fp);
|
|
X
|
|
X if (! (c1 >= '0' && c1 <= '7' &&
|
|
X c2 >= '0' && c2 <= '7' &&
|
|
X c3 >= '0' && c3 <= '7'))
|
|
X return EOF;
|
|
X
|
|
X c = ((c1 - '0') << 6) | ((c2 - '0') << 3) | (c3 - '0');
|
|
X return c;
|
|
X}
|
|
X
|
|
Xvoid
|
|
Xcomment (FILE * fp)
|
|
X{
|
|
X int c;
|
|
X
|
|
X while ((c = getc (fp)) != EOF && c != '\n')
|
|
X ;
|
|
X}
|
|
X
|
|
Xmessage (nl_catd catd, FILE * fp, int set)
|
|
X{
|
|
X int c;
|
|
X int i;
|
|
X enum { line_begin,
|
|
X number,
|
|
X text_begin, text_mid, text_end,
|
|
X done
|
|
X } state = line_begin;
|
|
X int quoted;
|
|
X char msg_num[16];
|
|
X int cur_msg;
|
|
X char line[NL_TEXTMAX+2];
|
|
X
|
|
X while (state != done) {
|
|
X if ((c = getc (fp)) == EOF) {
|
|
X if (state == text_mid) {
|
|
X state = done;
|
|
X continue;
|
|
X }
|
|
X invalid (fp);
|
|
X return;
|
|
X }
|
|
X if (state == line_begin) {
|
|
X if (c == EOF || ! isdigit (c)) {
|
|
X invalid (fp);
|
|
X return;
|
|
X }
|
|
X state = number;
|
|
X i = 1;
|
|
X msg_num[0] = c;
|
|
X continue;
|
|
X }
|
|
X if (state == number) {
|
|
X if (isdigit (c)) {
|
|
X if (i >= sizeof msg_num - 1) {
|
|
X invalid (fp);
|
|
X return;
|
|
X }
|
|
X msg_num[i++] = c;
|
|
X continue;
|
|
X }
|
|
X if (isspace (c)) {
|
|
X msg_num[i] = '\0';
|
|
X cur_msg = atoi (msg_num);
|
|
X if (cur_msg < 1 || cur_msg > NL_MSGMAX) {
|
|
X invalid (fp);
|
|
X return;
|
|
X }
|
|
X if (catd->nl_sets < set)
|
|
X catd->nl_sets = set;
|
|
X
|
|
X if (catd->nl_msgs[set-1] == 0) {
|
|
X catd->nl_msgs[set-1] = (off_t *)
|
|
X calloc (NL_MSGMAX,
|
|
X sizeof (off_t));
|
|
X }
|
|
X if (catd->nl_nmsgs[set-1] < cur_msg)
|
|
X catd->nl_nmsgs[set-1] = cur_msg;
|
|
X
|
|
X /*
|
|
X * Just a number? Delete the message from
|
|
X * the catalog.
|
|
X */
|
|
X
|
|
X if (c == '\n') {
|
|
X if (messages[set-1][cur_msg-1]) {
|
|
X free (messages[set-1][cur_msg-1]);
|
|
X messages[set-1][cur_msg-1] = 0;
|
|
X }
|
|
X return;
|
|
X }
|
|
X
|
|
X /*
|
|
X * Message ID followed by whitespace starts
|
|
X * a valid message. Reset the buffer pointer
|
|
X * to start collecting characters.
|
|
X */
|
|
X
|
|
X state = text_begin;
|
|
X i = 0;
|
|
X continue;
|
|
X }
|
|
X
|
|
X /*
|
|
X * There must be whitespace after the number.
|
|
X */
|
|
X
|
|
X invalid (fp);
|
|
X return;
|
|
X }
|
|
X
|
|
X /*
|
|
X * At the beginning of a message a single "quote" character
|
|
X * is allowed. If `c' is that character, discard it and
|
|
X * change state. Otherwise, push the charcter back because
|
|
X * it is part of the actual message text.
|
|
X */
|
|
X
|
|
X if (state == text_begin) {
|
|
X
|
|
X /*
|
|
X * No characters at all? This is an empty message.
|
|
X */
|
|
X
|
|
X if (c == '\n') {
|
|
X ungetc (c, fp);
|
|
X state = text_end;
|
|
X continue;
|
|
X }
|
|
X if (c != quotec)
|
|
X ungetc (c, fp);
|
|
X else
|
|
X quoted = 1;
|
|
X
|
|
X state = text_mid;
|
|
X continue;
|
|
X }
|
|
X
|
|
X if (state == text_mid) {
|
|
X if (quoted && c == quotec) {
|
|
X if ((c = getc (fp)) == EOF || c == '\n') {
|
|
X ungetc (c, fp);
|
|
X state = text_end;
|
|
X continue;
|
|
X } else {
|
|
X ungetc (c, fp);
|
|
X c = quotec;
|
|
X }
|
|
X }
|
|
X if (c == '\n') {
|
|
X ungetc (c, fp);
|
|
X state = text_end;
|
|
X continue;
|
|
X }
|
|
X if (c == '\\') {
|
|
X c = getc (fp);
|
|
X if (c == EOF) {
|
|
X invalid (fp);
|
|
X return;
|
|
X }
|
|
X if (c == '\n')
|
|
X continue;
|
|
X
|
|
X switch (c) {
|
|
X case 'n': c = '\n'; break;
|
|
X case 't': c = '\t'; break;
|
|
X case 'v': c = '\v'; break;
|
|
X case 'b': c = '\b'; break;
|
|
X case 'r': c = '\r'; break;
|
|
X case 'f': c = '\f'; break;
|
|
X case '\\': c = '\\'; break;
|
|
X default:
|
|
X if (isdigit (c)) {
|
|
X ungetc (c, fp);
|
|
X c = octal (fp);
|
|
X }
|
|
X if (c == EOF) {
|
|
X invalid (fp);
|
|
X return;
|
|
X }
|
|
X }
|
|
X }
|
|
X if (i < NL_TEXTMAX)
|
|
X line[i++] = c;
|
|
X
|
|
X continue;
|
|
X }
|
|
X
|
|
X if (state == text_end) {
|
|
X if (i < NL_TEXTMAX)
|
|
X line[i] = '\0';
|
|
X
|
|
X state = done;
|
|
X continue;
|
|
X }
|
|
X }
|
|
X if (i >= NL_TEXTMAX) {
|
|
X invalid (fp);
|
|
X return;
|
|
X }
|
|
X line[i] = '\0';
|
|
X
|
|
X if (messages[set-1] == (char **) 0) {
|
|
X messages[set-1] =
|
|
X (char **) malloc (sizeof (char *) * NL_MSGMAX);
|
|
X memset (messages[set-1], 0, sizeof (char *) * NL_MSGMAX);
|
|
X }
|
|
X if (messages[set-1][cur_msg-1])
|
|
X free (messages[set - 1][cur_msg - 1]);
|
|
X
|
|
X messages[set - 1][cur_msg - 1] = strdup (line);
|
|
X}
|
|
X
|
|
Xint
|
|
Xload_catalog (nl_catd new_catd)
|
|
X{
|
|
X int i, j, k;
|
|
X int c;
|
|
X nl_cat_header header;
|
|
X char buf[NL_TEXTMAX+1];
|
|
X
|
|
X if (fread (&header, sizeof header, 1, new_catd->nl_cat_fp) != 1)
|
|
X return -1;
|
|
X
|
|
X if (header.nl_sets < 1 || header.nl_sets > NL_SETMAX)
|
|
X return -1;
|
|
X
|
|
X new_catd->nl_sets = header.nl_sets;
|
|
X memcpy (new_catd->nl_nmsgs, header.nl_nmsgs, sizeof header.nl_nmsgs);
|
|
X
|
|
X for (i = 0;i < NL_SETMAX;i++) {
|
|
X if (! (new_catd->nl_msgs[i] = (off_t *) calloc
|
|
X (NL_MSGMAX, sizeof (off_t)))) {
|
|
X fprintf (stderr, M(11, "no memory"));
|
|
X exit (1);
|
|
X }
|
|
X if (! (messages[i] = (char **) calloc
|
|
X (NL_MSGMAX, sizeof (char *)))) {
|
|
X fprintf (stderr, M(11, "no memory"));
|
|
X exit (1);
|
|
X }
|
|
X if (new_catd->nl_nmsgs[i] == 0)
|
|
X continue;
|
|
X
|
|
X if (fread (new_catd->nl_msgs[i], sizeof (off_t),
|
|
X new_catd->nl_nmsgs[i], new_catd->nl_cat_fp) !=
|
|
X new_catd->nl_nmsgs[i])
|
|
X return -1;
|
|
X }
|
|
X for (i = 0;i < new_catd->nl_sets;i++) {
|
|
X for (j = 0;j < new_catd->nl_nmsgs[i];j++) {
|
|
X for (k = 0;(c = getc (new_catd->nl_cat_fp)) &&
|
|
X c != EOF && k < NL_TEXTMAX;)
|
|
X buf[k++] = c;
|
|
X
|
|
X if (k >= NL_TEXTMAX)
|
|
X return -1;
|
|
X
|
|
X buf[k] = '\0';
|
|
X if (! (messages[i][j] = strdup (buf))) {
|
|
X fprintf (stderr, M(11, "no memory"));
|
|
X exit (1);
|
|
X }
|
|
X }
|
|
X }
|
|
X return 0;
|
|
X}
|
|
X
|
|
Xmain (int argc, char ** argv)
|
|
X{
|
|
X int i, j;
|
|
X int c;
|
|
X int created = 0;
|
|
X nl_catd new_catd;
|
|
X nl_cat_header header;
|
|
X char error[BUFSIZ];
|
|
X int nerrors = 0;
|
|
X int cur_set = NL_SETD;
|
|
X FILE *input = 0;
|
|
X off_t base;
|
|
X
|
|
X catd = catopen ("gencat", 0);
|
|
X
|
|
X if (argc < 3) {
|
|
X fprintf (stderr, M(1, "usage: gencat catfile msgfile ...\n"));
|
|
X exit (1);
|
|
X }
|
|
X if (! (new_catd = (nl_catd) malloc (sizeof *new_catd))) {
|
|
X perror (M(4, "gencat: can't create new catalog descriptor"));
|
|
X exit (1);
|
|
X }
|
|
X memset (new_catd, 0, sizeof *new_catd);
|
|
X memset (&header, 0, sizeof header);
|
|
X
|
|
X /*
|
|
X * See if the file already exists. If it doesn't we will be
|
|
X * creating it from scratch.
|
|
X */
|
|
X
|
|
X if (access (argv[1], 0) == -1)
|
|
X created = 1;
|
|
X
|
|
X /*
|
|
X * Try to open the message catalog. If it exists, it will be
|
|
X * opened for read/update, if it doesn't we create a brand new
|
|
X * empty file.
|
|
X */
|
|
X
|
|
X if (! (new_catd->nl_cat_fp = fopen (argv[1], created ? "w":"r+"))) {
|
|
X if (created)
|
|
X sprintf (error, M(6, "gencat: can't create catalog %s"),
|
|
X argv[1]);
|
|
X else
|
|
X sprintf (error, M(9, "gencat: can't open catalog %s"),
|
|
X argv[1]);
|
|
X
|
|
X perror (error);
|
|
X exit (1);
|
|
X }
|
|
X
|
|
X /*
|
|
X * Initialize the catalog descriptor to completely empty. If
|
|
X * there was an existing catalog file, we're going to go load
|
|
X * it up in a second.
|
|
X */
|
|
X
|
|
X new_catd->nl_sets = 0;
|
|
X for (i = 0;i < NL_SETMAX;i++) {
|
|
X new_catd->nl_nmsgs[i] = 0;
|
|
X new_catd->nl_msgs[i] = (off_t *) 0;
|
|
X }
|
|
X if (! created) {
|
|
X if (load_catalog (new_catd)) {
|
|
X fprintf (stderr, M(10, "invalid catalog file %s\n"),
|
|
X argv[1]);
|
|
X exit (1);
|
|
X }
|
|
X }
|
|
X
|
|
X for (i = 2;i < argc;i++) {
|
|
X if (input && input != stdin) {
|
|
X fclose (input);
|
|
X input = 0;
|
|
X }
|
|
X if (strcmp (argv[i], "-") == 0) {
|
|
X input = stdin;
|
|
X } else if (! (input = fopen (argv[i], "r"))) {
|
|
X sprintf (error, M(7, "gencat: can't open %s"), argv[i]);
|
|
X perror (error);
|
|
X nerrors++;
|
|
X continue;
|
|
X }
|
|
X lineno = 0;
|
|
X if (argc > 3)
|
|
X printf ("%s:\n", argv[i]);
|
|
X
|
|
X while ((c = getc (input)) != EOF) {
|
|
X lineno++;
|
|
X if (c != '$') {
|
|
X ungetc (c, input);
|
|
X message (new_catd, input, cur_set);
|
|
X continue;
|
|
X }
|
|
X if ((c = getc (input)) == EOF)
|
|
X break;
|
|
X
|
|
X if (c == ' ' || c == '\t' || c == '\n') {
|
|
X if (c != '\n')
|
|
X comment (input);
|
|
X
|
|
X continue;
|
|
X }
|
|
X if (c == 's') {
|
|
X int new_set;
|
|
X
|
|
X ungetc (c, input);
|
|
X if (fscanf (input, "set%*[ ]%d%*[^\n]",
|
|
X &new_set) != 1) {
|
|
X invalid (input);
|
|
X nerrors++;
|
|
X continue;
|
|
X }
|
|
X if (new_set < 1 || new_set > NL_SETMAX) {
|
|
X invalid (input);
|
|
X nerrors++;
|
|
X continue;
|
|
X }
|
|
X getc (input);
|
|
X cur_set = new_set;
|
|
X continue;
|
|
X }
|
|
X if (c == 'd') {
|
|
X char old_set;
|
|
X
|
|
X ungetc (c, input);
|
|
X if (fscanf (input, "delset%*[ ]%d%*[^\n]",
|
|
X &old_set) != 1) {
|
|
X invalid (input);
|
|
X nerrors++;
|
|
X continue;
|
|
X }
|
|
X if (old_set < 1 || old_set >= NL_SETMAX) {
|
|
X invalid (input);
|
|
X nerrors++;
|
|
X continue;
|
|
X }
|
|
X memset (new_catd->nl_msgs[old_set - 1], 0,
|
|
X NL_MSGMAX * sizeof (off_t));
|
|
X new_catd->nl_nmsgs[old_set - 1] = 0;
|
|
X for (i = 0;i < NL_MSGMAX;i++) {
|
|
X if (messages[old_set-1][i])
|
|
X free (messages[old_set-1][i]);
|
|
X
|
|
X messages[old_set-1][i] = 0;
|
|
X }
|
|
X getc (input);
|
|
X continue;
|
|
X }
|
|
X if (c == 'q') {
|
|
X char new_quotec;
|
|
X
|
|
X ungetc (c, input);
|
|
X if (fscanf (input, "quote%*[ ]%c%*[^\n]\n",
|
|
X &new_quotec) != 1) {
|
|
X invalid (input);
|
|
X nerrors++;
|
|
X continue;
|
|
X }
|
|
X getc (input);
|
|
X quotec = new_quotec;
|
|
X continue;
|
|
X }
|
|
X }
|
|
X }
|
|
X
|
|
X /*
|
|
X * There were some errors and they were already reported. If we
|
|
X * created the message catalog go ahead and delete the file.
|
|
X */
|
|
X
|
|
X if (nerrors) {
|
|
X if (created)
|
|
X (void) unlink (argv[1]);
|
|
X
|
|
X exit (2);
|
|
X }
|
|
X
|
|
X /*
|
|
X * Scan the in-core message catalog information to determine
|
|
X * how many sets were defined and how many messages are in each
|
|
X * set. The information in the catalog descriptor right now
|
|
X * may be wrong as sets and messages may have been deleted.
|
|
X */
|
|
X
|
|
X for (i = 0;i < NL_SETMAX;i++) {
|
|
X
|
|
X /*
|
|
X * If there are no messages at all in the set, or there
|
|
X * never were, just say so and skip.
|
|
X */
|
|
X
|
|
X if (new_catd->nl_msgs[i] == (off_t *) 0 ||
|
|
X new_catd->nl_nmsgs[i] == 0) {
|
|
X new_catd->nl_nmsgs[i] = 0;
|
|
X continue;
|
|
X }
|
|
X
|
|
X /*
|
|
X * There must have been a message sometime in the past,
|
|
X * so set the count to zero and see what the highest
|
|
X * numbered one is now.
|
|
X */
|
|
X
|
|
X new_catd->nl_nmsgs[i] = 0;
|
|
X for (j = 0;j < NL_MSGMAX;j++) {
|
|
X if (messages[i][j])
|
|
X new_catd->nl_nmsgs[i] = j + 1;
|
|
X }
|
|
X
|
|
X /*
|
|
X * There weren't any? The last one must have been
|
|
X * deleted, so we completely delete the set now by saying
|
|
X * it has no messages.
|
|
X */
|
|
X
|
|
X if (new_catd->nl_nmsgs[i] == 0)
|
|
X continue;
|
|
X
|
|
X /*
|
|
X * This set has at least one message, make it the highest
|
|
X * numbered set.
|
|
X */
|
|
X
|
|
X new_catd->nl_sets = i + 1;
|
|
X }
|
|
X header.nl_sets = new_catd->nl_sets;
|
|
X memcpy (header.nl_nmsgs, new_catd->nl_nmsgs,
|
|
X new_catd->nl_sets * sizeof (off_t));
|
|
X
|
|
X base = sizeof header;
|
|
X for (i = 0;i < new_catd->nl_sets;i++)
|
|
X base += new_catd->nl_nmsgs[i] * sizeof (off_t);
|
|
X
|
|
X for (i = 0;i < new_catd->nl_sets;i++) {
|
|
X for (j = 0;j < new_catd->nl_nmsgs[i];j++) {
|
|
X if (messages[i][j] == (char *) 0) {
|
|
X new_catd->nl_msgs[i][j] = 0;
|
|
X continue;
|
|
X }
|
|
X new_catd->nl_msgs[i][j] = base;
|
|
X base += strlen (messages[i][j]) + 1;
|
|
X }
|
|
X }
|
|
X if (! created) {
|
|
X if (! (new_catd->nl_cat_fp = fopen (argv[1], "w"))) {
|
|
X sprintf (error, M(6, "gencat: can't create catalog %s"),
|
|
X argv[1]);
|
|
X perror (error);
|
|
X exit (1);
|
|
X }
|
|
X }
|
|
X if (fwrite (&header, sizeof header, 1, new_catd->nl_cat_fp) != 1) {
|
|
X sprintf (error, M(8, "gencat: can't write to %s"), argv[1]);
|
|
X perror (error);
|
|
X exit (1);
|
|
X }
|
|
X for (i = 0;i < new_catd->nl_sets;i++) {
|
|
X if (new_catd->nl_nmsgs[i] == 0)
|
|
X continue;
|
|
X
|
|
X if (fwrite (new_catd->nl_msgs[i], sizeof (off_t),
|
|
X new_catd->nl_nmsgs[i], new_catd->nl_cat_fp) !=
|
|
X new_catd->nl_nmsgs[i]) {
|
|
X sprintf (error,
|
|
X M(8, "gencat: can't write to %s"), argv[1]);
|
|
X perror (error);
|
|
X exit (1);
|
|
X }
|
|
X }
|
|
X for (i = 0;i < new_catd->nl_sets;i++) {
|
|
X if (new_catd->nl_msgs[i] == (off_t *) 0)
|
|
X continue;
|
|
X
|
|
X for (j = 0;j < new_catd->nl_nmsgs[i];j++) {
|
|
X if (messages[i][j] == (char *) 0)
|
|
X continue;
|
|
X
|
|
X if (fwrite (messages[i][j],
|
|
X strlen (messages[i][j]) + 1, 1,
|
|
X new_catd->nl_cat_fp) != 1) {
|
|
X sprintf (error,
|
|
X M(8, "gencat: can't write to %s"),
|
|
X argv[1]);
|
|
X perror (error);
|
|
X exit (1);
|
|
X }
|
|
X }
|
|
X }
|
|
X exit (0);
|
|
X}
|
|
SHAR_EOF
|
|
chmod 0644 gencat.c || echo "restore of gencat.c fails"
|
|
sed 's/^X//' << 'SHAR_EOF' > gencat.msg.En_US &&
|
|
X$quote "
|
|
X$
|
|
X$ message catalog for "gencat"
|
|
X$
|
|
X$set 1
|
|
X1 Usage: gencat catfile msgfile ...\n
|
|
X2 gencat: Unable to open the file %s\n
|
|
X3 Invalid line in input file, line %d\n
|
|
X4 gencat: Unable to create new message catalog\n
|
|
X5 gencat: Unable to create temporary file\n
|
|
X6 gencat: Unable to create message catalog file %s
|
|
X7 gencat: Unable to open message file %s
|
|
X8 gencat: Unable to write to message catalog file %s
|
|
X9 gencat: Unable to open message catalog file %s
|
|
X10 gencat: The file %s is not a valid message catalog\n
|
|
X11 gencat: Out of memory loading message catalog
|
|
X$
|
|
X$ message catalog for "catgets"
|
|
X$
|
|
X$set 2
|
|
X1 Usage: catgets catalog set msg default\n
|
|
X$
|
|
X$ message catalog for "dspcat"
|
|
X$
|
|
X$set 3
|
|
X1 Usage: dspcat catalog [ set [ msg ] ]\n
|
|
X2 dspcat: Unable to open message catalog file %s\n
|
|
X3 dspcat: "%s" is an invalid set number.\n
|
|
X4 dspcat: "%s" is an invalid message number.\n
|
|
SHAR_EOF
|
|
chmod 0644 gencat.msg.En_US || echo "restore of gencat.msg.En_US fails"
|
|
sed 's/^X//' << 'SHAR_EOF' > catgets.c &&
|
|
X/*
|
|
X * Copyright 1994, John F. Haugh II
|
|
X * All rights reserved.
|
|
X *
|
|
X * Permission is granted to copy and create derivative works for any
|
|
X * non-commercial purpose, provided this copyright notice is preserved
|
|
X * in all copies of source code, or included in human readable form
|
|
X * and conspicuously displayed on all copies of object code or
|
|
X * distribution media.
|
|
X *
|
|
X * This software is provided on an AS-IS basis and the author makes
|
|
X * no warrantee of any kind. The "Artistic License" located in the
|
|
X * file LICENSE contains complete licensing information.
|
|
X */
|
|
X
|
|
X#ifndef lint
|
|
Xstatic char sccsid[] = "%W% %U% %G%";
|
|
X#endif
|
|
X
|
|
X#include <stdio.h>
|
|
X#include "nl_types.h"
|
|
X
|
|
Xnl_catd catd;
|
|
X#define M(msg,def) catgets (catd, 2, msg, def)
|
|
X
|
|
Xmain (int argc, char ** argv)
|
|
X{
|
|
X nl_catd cmd_catd;
|
|
X char *msg;
|
|
X
|
|
X catd = catopen ("gencat", 0);
|
|
X
|
|
X if (argc < 5) {
|
|
X fprintf (stderr,
|
|
X M(1, "usage: catgets catalog set msg default\n"));
|
|
X exit (1);
|
|
X }
|
|
X cmd_catd = catopen (argv[1], 0);
|
|
X if (msg = catgets (cmd_catd, atoi (argv[2]), atoi (argv[3]), argv[4]))
|
|
X write (1, msg, strlen (msg));
|
|
X else
|
|
X write (1, argv[4], strlen (argv[4]));
|
|
X
|
|
X exit (1);
|
|
X}
|
|
SHAR_EOF
|
|
chmod 0644 catgets.c || echo "restore of catgets.c fails"
|
|
sed 's/^X//' << 'SHAR_EOF' > l_catclose.c &&
|
|
X/*
|
|
X * Copyright 1994, John F. Haugh II
|
|
X * All rights reserved.
|
|
X *
|
|
X * Permission is granted to copy and create derivative works for any
|
|
X * non-commercial purpose, provided this copyright notice is preserved
|
|
X * in all copies of source code, or included in human readable form
|
|
X * and conspicuously displayed on all copies of object code or
|
|
X * distribution media.
|
|
X *
|
|
X * This software is provided on an AS-IS basis and the author makes
|
|
X * no warrantee of any kind. The "Artistic License" located in the
|
|
X * file LICENSE contains complete licensing information.
|
|
X */
|
|
X
|
|
X#ifndef lint
|
|
Xstatic char sccsid[] = "%W% %U% %G%";
|
|
X#endif
|
|
X
|
|
X#include <sys/types.h>
|
|
X#include <stdio.h>
|
|
X#include "nl_types.h"
|
|
X
|
|
Xint
|
|
Xcatclose (nl_catd catd)
|
|
X{
|
|
X int i;
|
|
X
|
|
X if (catd == (nl_catd) -1)
|
|
X return -1;
|
|
X
|
|
X fclose (catd->nl_cat_fp);
|
|
X
|
|
X for (i = 0;i <= catd->nl_sets;i++)
|
|
X if (catd->nl_msgs[i])
|
|
X free (catd->nl_nmsgs);
|
|
X
|
|
X free (catd);
|
|
X return 0;
|
|
X}
|
|
SHAR_EOF
|
|
chmod 0644 l_catclose.c || echo "restore of l_catclose.c fails"
|
|
sed 's/^X//' << 'SHAR_EOF' > l_catgets.c &&
|
|
X/*
|
|
X * Copyright 1994, John F. Haugh II
|
|
X * All rights reserved.
|
|
X *
|
|
X * Permission is granted to copy and create derivative works for any
|
|
X * non-commercial purpose, provided this copyright notice is preserved
|
|
X * in all copies of source code, or included in human readable form
|
|
X * and conspicuously displayed on all copies of object code or
|
|
X * distribution media.
|
|
X *
|
|
X * This software is provided on an AS-IS basis and the author makes
|
|
X * no warrantee of any kind. The "Artistic License" located in the
|
|
X * file LICENSE contains complete licensing information.
|
|
X */
|
|
X
|
|
X#ifndef lint
|
|
Xstatic char sccsid[] = "%W% %U% %G%";
|
|
X#endif
|
|
X
|
|
X#include <sys/types.h>
|
|
X#include <stdio.h>
|
|
X#include "nl_types.h"
|
|
X
|
|
Xchar *
|
|
Xcatgets (nl_catd catd, int set_num, int msg_num, char * def_msg)
|
|
X{
|
|
X static char buf[NL_TEXTMAX];
|
|
X int i;
|
|
X int c;
|
|
X
|
|
X if (catd == (nl_catd) -1)
|
|
X return def_msg;
|
|
X
|
|
X if (set_num < 1 || set_num > catd->nl_sets)
|
|
X return def_msg;
|
|
X
|
|
X if (msg_num < 1 || msg_num > catd->nl_nmsgs[set_num-1])
|
|
X return def_msg;
|
|
X
|
|
X if (catd->nl_msgs[set_num-1][msg_num-1] == (off_t) 0)
|
|
X return def_msg;
|
|
X
|
|
X if (fseek (catd->nl_cat_fp, catd->nl_msgs[set_num-1][msg_num-1], 0))
|
|
X return def_msg;
|
|
X
|
|
X for (i = 0;i < (NL_TEXTMAX-1);i++) {
|
|
X if ((c = getc (catd->nl_cat_fp)) == '\0' || c == EOF)
|
|
X break;
|
|
X
|
|
X buf[i] = c;
|
|
X }
|
|
X buf[i++] = '\0';
|
|
X return buf;
|
|
X}
|
|
SHAR_EOF
|
|
chmod 0644 l_catgets.c || echo "restore of l_catgets.c fails"
|
|
sed 's/^X//' << 'SHAR_EOF' > l_catopen.c &&
|
|
X/*
|
|
X * Copyright 1994, John F. Haugh II
|
|
X * All rights reserved.
|
|
X *
|
|
X * Permission is granted to copy and create derivative works for any
|
|
X * non-commercial purpose, provided this copyright notice is preserved
|
|
X * in all copies of source code, or included in human readable form
|
|
X * and conspicuously displayed on all copies of object code or
|
|
X * distribution media.
|
|
X *
|
|
X * This software is provided on an AS-IS basis and the author makes
|
|
X * no warrantee of any kind. The "Artistic License" located in the
|
|
X * file LICENSE contains complete licensing information.
|
|
X */
|
|
X
|
|
X#ifndef lint
|
|
Xstatic char sccsid[] = "%W% %U% %G%";
|
|
X#endif
|
|
X
|
|
X#include <limits.h>
|
|
X#include <unistd.h>
|
|
X#include <stdlib.h>
|
|
X#include <string.h>
|
|
X#include <stdio.h>
|
|
X
|
|
X#undef NL_MSGMAX
|
|
X#undef NL_SETMAX
|
|
X#undef NL_TEXTMAX
|
|
X
|
|
X#include "nl_types.h"
|
|
X
|
|
Xstatic char lang_var[32];
|
|
Xstatic char language[16];
|
|
Xstatic char territory[16];
|
|
Xstatic char codeset[16];
|
|
X
|
|
Xstatic void
|
|
Xget_lang_var ()
|
|
X{
|
|
X char *lang;
|
|
X
|
|
X if (! (lang = getenv ("LANG")))
|
|
X lang = "C";
|
|
X
|
|
X strncpy (lang_var, lang, sizeof lang_var);
|
|
X
|
|
X switch (sscanf (lang_var, "%16[^_]_%16[^.].%16s",
|
|
X language, territory, codeset)) {
|
|
X default:
|
|
X case 0:
|
|
X language[0] = '\0';
|
|
X case 1:
|
|
X territory[0] = '\0';
|
|
X case 2:
|
|
X codeset[0] = '\0';
|
|
X case 3:
|
|
X return;
|
|
X }
|
|
X}
|
|
X
|
|
Xstatic int
|
|
Xget_cat_name (char * file, const char * path, const char * name)
|
|
X{
|
|
X char *begin, *end;
|
|
X char *cp1, *cp2;
|
|
X char dummy[BUFSIZ];
|
|
X
|
|
X strncpy (dummy, path, sizeof dummy - 1);
|
|
X dummy[BUFSIZ-1] = '\0';
|
|
X file[0] = '\0';
|
|
X
|
|
X for (begin = dummy;begin;begin = end) {
|
|
X if (end = strchr (begin, ':'))
|
|
X *end++ = '\0';
|
|
X
|
|
X for (cp1 = begin, cp2 = file;*cp1;) {
|
|
X if (*cp1 != '%') {
|
|
X *cp2++ = *cp1++;
|
|
X continue;
|
|
X }
|
|
X switch (*++cp1) {
|
|
X default:
|
|
X case '%':
|
|
X *cp2++ = *cp1++;
|
|
X continue;
|
|
X case 'N':
|
|
X strcpy (cp2, name);
|
|
X cp1++;
|
|
X cp2 += strlen (name);
|
|
X continue;
|
|
X case 'L':
|
|
X strcpy (cp2, lang_var);
|
|
X cp1++;
|
|
X cp2 += strlen (lang_var);
|
|
X continue;
|
|
X case 'l':
|
|
X strcpy (cp2, language);
|
|
X cp1++;
|
|
X cp2 += strlen (language);
|
|
X continue;
|
|
X case 't':
|
|
X strcpy (cp2, territory);
|
|
X cp1++;
|
|
X cp2 += strlen (territory);
|
|
X continue;
|
|
X case 'c':
|
|
X strcpy (cp2, codeset);
|
|
X cp1++;
|
|
X cp2 += strlen (codeset);
|
|
X continue;
|
|
X }
|
|
X }
|
|
X *cp2 = '\0';
|
|
X
|
|
X if (access (file, 0) == 0)
|
|
X return 0;
|
|
X }
|
|
X return -1;
|
|
X}
|
|
X
|
|
Xnl_catd
|
|
Xcatopen (const char * name, int oflag)
|
|
X{
|
|
X char *nlspath;
|
|
X char catalog[PATH_MAX];
|
|
X int i;
|
|
X nl_catd catd;
|
|
X nl_cat_header header;
|
|
X
|
|
X if (! (nlspath = getenv ("NLSPATH")))
|
|
X nlspath = "/usr/lib/nls/%L/%N.cat";
|
|
X
|
|
X get_lang_var ();
|
|
X
|
|
X if (strcmp (language, "C") == 0)
|
|
X return (nl_catd) -1;
|
|
X
|
|
X if (get_cat_name (catalog, nlspath, name))
|
|
X return (nl_catd) -1;
|
|
X
|
|
X if (! (catd = (nl_catd) malloc (sizeof *catd)))
|
|
X return (nl_catd) -1;
|
|
X
|
|
X if (! (catd->nl_cat_fp = fopen (catalog, "r"))) {
|
|
X free (catd);
|
|
X return (nl_catd) -1;
|
|
X }
|
|
X if (fread (&header, sizeof header, 1, catd->nl_cat_fp) != 1) {
|
|
X fclose (catd->nl_cat_fp);
|
|
X free (catd);
|
|
X return (nl_catd) -1;
|
|
X }
|
|
X catd->nl_sets = header.nl_sets;
|
|
X for (i = 0;i < catd->nl_sets;i++)
|
|
X catd->nl_msgs[i] = (off_t *) 0;
|
|
X
|
|
X for (i = 0;i < header.nl_sets;i++) {
|
|
X catd->nl_nmsgs[i] = header.nl_nmsgs[i];
|
|
X
|
|
X if (catd->nl_nmsgs[i] == 0) {
|
|
X catd->nl_msgs[i] = (off_t *) 0;
|
|
X continue;
|
|
X }
|
|
X if (! (catd->nl_msgs[i] = (off_t *)
|
|
X malloc (sizeof (off_t) * header.nl_nmsgs[i])))
|
|
X goto fail;
|
|
X if (fread (catd->nl_msgs[i], sizeof (off_t) *
|
|
X header.nl_nmsgs[i], 1, catd->nl_cat_fp) != 1)
|
|
X goto fail;
|
|
X }
|
|
X return catd;
|
|
X
|
|
Xfail:
|
|
X fclose (catd->nl_cat_fp);
|
|
X
|
|
X for (i = 0;i <= catd->nl_sets;i++)
|
|
X if (catd->nl_msgs[i])
|
|
X free (catd->nl_nmsgs);
|
|
X
|
|
X free (catd);
|
|
X return (nl_catd) -1;
|
|
X}
|
|
SHAR_EOF
|
|
chmod 0644 l_catopen.c || echo "restore of l_catopen.c fails"
|
|
sed 's/^X//' << 'SHAR_EOF' > nl_types.h &&
|
|
X/*
|
|
X * Copyright 1994, John F. Haugh II
|
|
X * All rights reserved.
|
|
X *
|
|
X * Permission is granted to copy and create derivative works for any
|
|
X * non-commercial purpose, provided this copyright notice is preserved
|
|
X * in all copies of source code, or included in human readable form
|
|
X * and conspicuously displayed on all copies of object code or
|
|
X * distribution media.
|
|
X *
|
|
X * This software is provided on an AS-IS basis and the author makes
|
|
X * no warrantee of any kind. The "Artistic License" located in the
|
|
X * file LICENSE contains complete licensing information.
|
|
X *
|
|
X * %W% %U% %G%
|
|
X */
|
|
X
|
|
X#define NL_MSGMAX 256
|
|
X#define NL_SETD 1
|
|
X#define NL_SETMAX 16
|
|
X#define NL_TEXTMAX 1024
|
|
X
|
|
Xtypedef struct {
|
|
X FILE *nl_cat_fp;
|
|
X int nl_sets;
|
|
X int nl_nmsgs[NL_SETMAX];
|
|
X off_t *nl_msgs[NL_SETMAX];
|
|
X} * nl_catd;
|
|
X
|
|
Xtypedef struct {
|
|
X int nl_sets;
|
|
X int nl_nmsgs[NL_SETMAX];
|
|
X} nl_cat_header;
|
|
X
|
|
Xnl_catd catopen (const char *, int);
|
|
Xint catclose (nl_catd);
|
|
Xchar *catgets (nl_catd, int, int, char *);
|
|
SHAR_EOF
|
|
chmod 0644 nl_types.h || echo "restore of nl_types.h fails"
|
|
exit 0
|
|
--
|
|
John F. Haugh II [ NRA-ILA ] [ Kill Barney ] !'s: ...!cs.utexas.edu!rpp386!jfh
|
|
Ma Bell: (512) 251-2151 [GOP][DoF #17][PADI][ENTJ] @'s: jfh@rpp386.cactus.org
|
|
There are three documents that run my life: The King James Bible, the United
|
|
States Constitution, and the UNIX System V Release 4 Programmer's Reference.
|
|
|
|
------------------------------
|
|
|
|
|
|
** FOR YOUR REFERENCE **
|
|
|
|
The service address, to which questions about the list itself and requests
|
|
to be added to or deleted from it should be directed, is:
|
|
|
|
Internet: Linux-Development-Request@NEWS-DIGESTS.MIT.EDU
|
|
|
|
You can send mail to the entire list (and comp.os.linux.development) via:
|
|
|
|
Internet: Linux-Development@NEWS-DIGESTS.MIT.EDU
|
|
|
|
Linux may be obtained via one of these FTP sites:
|
|
nic.funet.fi pub/OS/Linux
|
|
tsx-11.mit.edu pub/linux
|
|
sunsite.unc.edu pub/Linux
|
|
|
|
End of Linux-Development Digest
|
|
******************************
|