[news.software.notes] Notes Across NFS

shep@datacube.UUCP (12/12/87)

Hi. We've been running notes on our Pyramid 90X for about three years now.
I'm not sure what version we have except that Rich Salz came in about a year
ago to tune things up. Anyhow, since then we have added a few dozen suns
to our NFS. It would be great if we could use the Pyramid as the noteserver
and compile a sun binary to just read and write notes. (This would eliminate
the need to rlogin to the Pyramid).

I started looking into this and immediately ran into the fact that the Pyramid
pads its structs differently than the sun (on longword bounds). Things like
when_f and thus resp_f have different sizes on the two machines. A gut 
reaction would be to pad the suns structs to allign with the Pyramid's.
I thought I would post before I waste lots of time.

Has anyone else done this or know a better solution? Thanks in advance.

Shep Siegel
Datacube Inc.  DSP Products Group  4 Dearborn Rd. Peabody, Ma. 01960
UUCP: shep@datacube.COM
VOICE: (617) 535-6644;  FAX: (617) 535-5643;  TWX: (710) 347-0125

berliner@convexs.UUCP (12/27/87)

Well, we also have many Suns and also ran into the problem of structure
padding between the Sun and Convex C1 architectures.  I really don't know
how the Pyramid pads its structures, but the following may do the trick for
you.

The Sun pads both ints and shorts to a 2-byte boundary.  A Convex machine
pads ints to a 4-byte boundary, and a short to a 2-byte boundary.  The
Pyramid may indeed do the same thing as the Convex...

Anyway, here's the structs.h file that we used.  Look for "#ifdef sun" to
see the changes I made.  I'm not sure what local changes we've made, so
you'll likely just want to pick up the #ifdef sun lines and add them to
your structs.h and recompile the world on the Sun.  Good luck.

NOTE: this is based originally on Notes version 1.7, and like I say, there
may be some unusual local hacks added, but this is the basic idea.  I
compiled and ran the following program on the Convex and Sun to determine
which structures needed padding.  If all else fails, try this..

#include "parms.h"
#include "structs.h"
#include "dump.h"
#include "newsgate.h"
#include <pwd.h>
#include <grp.h>

main()
{
    struct auth_f auth_f_struct;
    struct when_f when_f_struct;
    struct perm_f perm_f_struct;
    struct daddr_f daddr_f_struct;
    struct txtbuf_f txtbuf_f_struct;
    struct dsply_f dsply_f_struct;
    struct resp_f resp_f_struct;
    struct note_f note_f_struct;
    struct descr_f descr_f_struct;
    struct io_f io_f_struct;
    struct id_f id_f_struct;
    struct seq_f seq_f_struct;
    struct nflist_f nflist_f_struct;
    struct dump_f dump_f_struct;
    struct hbuf hbuf_struct;
    struct passwd passwd_struct;
    struct group group_struct;

    printf("size of auth_f is %d\n", sizeof(auth_f_struct));
    printf("size of when_f is %d\n", sizeof(when_f_struct));
    printf("size of perm_f is %d\n", sizeof(perm_f_struct));
    printf("size of daddr_f is %d\n", sizeof(daddr_f_struct));
    printf("size of txtbuf_f is %d\n", sizeof(txtbuf_f_struct));
    printf("size of dsply_f is %d\n", sizeof(dsply_f_struct));
    printf("size of resp_f is %d\n", sizeof(resp_f_struct));
    printf("size of note_f is %d\n", sizeof(note_f_struct));
    printf("size of descr_f is %d\n", sizeof(descr_f_struct));
    printf("size of io_f is %d\n", sizeof(io_f_struct));
    printf("size of id_f is %d\n", sizeof(id_f_struct));
    printf("size of seq_f is %d\n", sizeof(seq_f_struct));
    printf("size of nflist_f is %d\n", sizeof(nflist_f_struct));
    printf("size of dump_f is %d\n", sizeof(dump_f_struct));
    printf("size of hbuf is %d\n", sizeof(hbuf_struct));
    printf("size of passwd is %d\n", sizeof(passwd_struct));
    printf("size of group is %d\n", sizeof(group_struct));
}

-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
Brian <nogger> Berliner				What is a nogger, anyway?
Convex Computer Corp.
UUCP: {ihnp4, uiucdcs, sun, rice, allegra}!convex!berliner
ARPA: convex!berliner@rice.arpa

-------- Cut here ------------------ Cut here ------------------
/*	$CHeader: structs.h 1.1 87/11/23 00:39:53 $	*/
/*	Copyright 1985 Convex Computer Corp.	*/
#include <stdio.h>

#if	defined(RCSIDENT) && defined(MAINLINE)
static char zzstructs[] = "$Header: /usr/src/local/notes/src/RCS/structs.h,v 1.1 87/11/23 00:39:53 root Exp $";
#endif	defined(RCSIDENT) && defined(MAINLINE)

/*
 *	structure definitions for the notesfile program.
 *
 *	Constants/definitions likely to change with different
 *	kernels are included in the file "parms.h".
 */


#define	TRUE	1					/* pretty euphemisms */
#define	FALSE	0
#define	NEVER	(-1)					/* expiration stuff */
#define	EDIT	TRUE					/* whether to edit or */
#define	NOEDIT	FALSE					/* not to edit */

#ifdef	UID8						/* 8 bit uids */
#define		UIDMASK 0377				/* mask 8 bit uids */
#define		GIDMASK 0377				/* mask 8 bit gids */
#else	! defined(UID8)					/* 16 bit uids */
#define		UIDMASK	0177777				/* mask out high UID bits */
#define		GIDMASK 0177777				/* mask out high GID bits */
#endif	! defined(UID8)

#define		NETLOG	"net.log"			/* network logfile */
#define		GRIPES	"nfgripes"			/* gripe notesfile */
#define		UTILITY	".utilities"			/* utility directory */
#define		LOCKS	".locks"			/* lock directory */
#define		SEQUENCER ".sequencer"			/* sequencer files */
#define		SEQ	".SEQ"				/* next d_nfnum */
#define		INDXHLP	"index.help"			/* index page help */
#define		RDMHLP	"read.help"			/* readem page help file */
#define		LIMHLP	"lim.help"			/* help for limited index */
#define		ACCHLP	"access.help"			/* for access editor */
#define		DIRHLP	"dir.help"			/* for director options */
#define		AVAILHLP "avail.notes"			/* list of public notefiles */
#define		NFCOMMENT "nfcomment"			/* nfcomment routine */
#define		ARCHALIAS "Archive-into"		/* archive mapping */

#define		TEXT	"text"				/* name of text file */
#define		INDEXN	"note.indx"			/* master index */
#define		INDEXR	"resp.indx"			/* response chains */
#define		ACCESS	"access"			/* access lists here */
#define		ARCHIVE	"archive"			/* archive sub-dir */
#define		COMPRESS "comp."			/* compress names */
#define		SEQLOCK		's'			/* .SEQ lock */
#define		LOGLOCK		'l'			/* log file locking */
#define		ARCHLOCK	'a'			/* archiving */
#define		TXTLOCK		't'			/* text file */
#define		DSCRLOCK 	'n'			/* index file */

#define		RESPSZ	5				/* number responses/response record */
#define		NAMESZ	17				/* longest user name */
#define		HOMESYSSZ	33			/* user home system */
#define		SYSSZ	33				/* system name length */
							/* above hold null byte also */
#define		BUFSIZE 1024				/* chars in core */

/*
 *	pick an appropriate default for the maximum message length
 *	(MAXMSG). Also pick an appropriate hard limit. (HARDMAX)
 *	HARDMAX must leave room for a one line message of up to 50
 *	bytes of the form "ignoring %ld excess bytes"
 */
#ifdef	BIGTEXT
#define		MAXMSG	100000				/* can be larger */
#define		HARDMAX	3000000				/* 3 Mbytes */
#else	NOT BIGTEXT
#define		MAXMSG	65000				/* not much larger */
#define		HARDMAX	65000				/* room for mesage */
#endif	NOT BIGTEXT
#define		PAGESAV	50				/* display stack */
							/* using unsigned short */
#define		UNIQPLEX 100000				/* multiplex nfid into noteid */
							/* see putnote and putresp */

#define		TITLEN	36				/* note title length */
#define		NNLEN	40				/* Notesfile Name length */
#define		DMLEN	40				/* director message length */
#define		NOT	~				/* tilde, prints wrong on hazeltines */
#define		WDLEN	128				/* longest file name */
#define		CMDLEN	512				/* build-a-command */
#define		PASSWDLEN 128				/* longest line in /etc/passwd */
#define		DATELEN	24				/* length of formatted date */
#define		NPERMS	35				/* max access list */
/*
 *	NPERMS can be increased as desired. However, a static array is
 *	allocated based on this constant. Watch it if you are running in
 *	a memory starved environment (like an 11/60).
 */
#define		PAGELEN	56				/* pagelength for 'S' */

#define		ANONOK	   01				/* permit anon notes */
#define		FRMNEWS    01				/* non-nf article */
#define		OPEN	   02				/* open for public */
#define		DIRMES	   04				/* director msg on */
#define		DELETED	   010				/* is deleted */
#define		NFINVALID  010				/* got bad copy */
#define		NETWRKD	   020				/* networking OK */
#define		CONTINUED  040				/* was auto-split */
#define		WRITONLY   0100				/* writeonly access when written */
#define		ORPHND	   0200				/* foster parent */
#define		ISARCH	   0400				/* is an archive */
#define		PROPCHG	  01000				/* propagate director message/title changes */

/*	change these only after modifying the table in access.c		*/
#define		READOK	01				/* allow user to read */
#define		WRITOK	02				/* allow user to write */
#define		DRCTOK	04				/* allow user to be director */
#define		RESPOK  010				/* ok to respond */
/*
 *	archive writing keyed on director status for now...
 */
#define		ARCHWRITOK  020				/* archive write */
#define		ARCHRESPOK 040				/* archive response */
#define		DFLTPERMS (READOK+WRITOK+RESPOK)	/* default permissions */

#define		PERMUSER	00			/* perm_f entry type */
#define		PERMGROUP	01			/* ORDER IS IMPORTANT */
#define		PERMSYSTEM	02


/*
 *	Sequencer modes.
 *	modes < NOREADSEQ cause the time to be taken from "Basetime"
 *	modes < NOWRITESEQ cause no update when leaving the notesfile.
 *	There is currently no way to read from the sequencer file
 *		and not update -- it's a wierd case anyway.
 */

#define		NOSEQ		0			/* no sequencer */
#define		USERSEQ		1			/* usertime noupdate */

#define		NOWRITESEQ	10			/* < this no write */
#define		BASESEQ		11			/* usertime & update */

#define		NOREADSEQ	100			/* use Basetime if < */
#define		NORMSEQ		101			/* normal sequencer */
#define		EXTSEQ		102			/* enter anyway */
#define		INDXSEQ		103			/* index sequencer */
							/*  from harpo!mmp */

#define		QUITSEQ		-2			/* quit, update sequencer */
#define		QUITNOSEQ	-3			/* quit, no seq update */
#define		QUITFAST	-4			/* quit almost abort */
#define		QUITUPD		-5			/* like quitfast */
#define		QUITNEX		-6			/* no notesfile */
#define		QUITBAD		-7			/* bad notesfile */

#define		GOOD		0			/* good exit status */
#define		BAD		1			/* bad exit status */
#define		NONF		2			/* no notefile */

#define		POLICY		1			/* mnemonics */
#define		NOPOLICY	0			/* used in calls */
#define		LOCKIT		1			/* Do not change */
#define		NOLOCKIT	0
#define		COPYID		1
#define		NOCOPYID	0
#define		ADDID		1
#define		NOADDID		0
#define		ADDTIME		1
#define		NOADDTIME	0
#define		DETAIL		1			/* dump extra info */
#define		NODETAIL	0			/* used for generic form */

/*
 *	These defines are for the archiver. They are used for determining
 *	eligibility for archival along with the age of the note.
 *	DFLT means to use whatever value was supplied on the archive
 *	command line.  The others mean the notesfile is configured
 *	for a specific archival setup.
 */

#define		DIRDFLT		0			/* use cmd line */
#define		DIRNOCARE	1			/* don't check dir */
#define		DIRON		2			/* only if dir on */
#define		DIROFF		3			/* only if dir off */

#define		KEEPDFLT	0			/* use cmd line */
#define		KEEPNO		1			/* delete 'em */
#define		KEEPYES		2			/* archive 'em */

struct auth_f						/* how we id author */
{
    char    aname[NAMESZ];				/* his name */
    char    asystem[HOMESYSSZ];				/* his system */
#ifdef sun
    short   pad;					/* pad for suns */
#endif sun
    int     aid;					/* uid (if local) */
};

struct when_f						/* standard date structure */
{
    short   w_year;
    short   w_month;
    short   w_day;
    short   w_hours;
    short   w_mins;
#ifdef sun
    short pad;
#endif sun
    long    w_gmttime;					/* stock unix time */
};

struct id_f						/* unique id for notes */
{
    char    sys[SYSSZ];
#ifdef sun
    short   pad;
#endif sun
    long    uniqid;
};

struct perm_f						/* permission tables */
{
    short   ptype;					/* user, group, system */
    char    name[NAMESZ];				/* name of such */
    short   perms;					/* what he is allowed */
};

struct daddr_f						/* save a disk address */
{
    long    addr;					/* for lseeks */
#ifdef	BIGTEXT
    unsigned long   textlen;				/* how long is text */
#else	NOT BIGTEXT
    unsigned short  textlen;				/* how long the text is */
#endif	NOT BIGTEXT
};

struct txtbuf_f
{
    char    txtbuf[BUFSIZE];				/* hold a bunch of characters */
};

struct dsply_f
{
    struct daddr_f  d_head;				/* text start */
    struct txtbuf_f d_buf;
    int     optr,
            olim;					/* output index and end of buffer */
    long    outcount;					/* number of characters dumped */
};

struct resp_f						/* for each response: */
{
    short   r_first,					/* bounds of this */
            r_last;					/* resp_f block */
    struct id_f r_id[RESPSZ];				/* system/id for each response */

    struct daddr_f  r_addr[RESPSZ];			/* where the response is */
    struct when_f   r_when[RESPSZ];			/* date/time of response */
    char    r_from[RESPSZ][SYSSZ];			/* system that sent this to us */
#ifdef sun
    short  pad;
#endif sun
    struct when_f   r_rcvd[RESPSZ];			/* date/time for sequencer */
    struct auth_f   r_auth[RESPSZ];
    char    r_stat[RESPSZ];				/* director/status flag */
#ifdef sun
    short pad2;
#endif sun
    int     r_next;					/* index of next response_ind */
    int     r_previous;					/* backlinks */
							/* [currently unused */
};

struct note_f						/* standard note structure: */
{
    struct id_f n_id;					/* unique id for this note */
    short   n_nresp;					/* number of responses */
    char    ntitle[TITLEN];				/* title of note */
#ifdef sun
    short  pad;
#endif sun
    struct auth_f   n_auth;				/* note's author */
    struct when_f   n_date;				/* note's date */
    struct when_f   n_rcvd;				/* date we got it */
    struct when_f   n_lmod;				/* date of last mod */
    struct when_f   n_dmchg;				/* date of last director message change */
    struct when_f   n_tchg;				/* date of last title change */
    char    n_from[SYSSZ];				/* system that handed us the note */
#ifdef sun
    short pad2;
#endif sun
    int     n_rindx;					/* where the first set of responses lies */
    struct daddr_f  n_addr;				/* address of note's text on disk */
    char    n_stat;					/* director/status flag */
#ifdef sun
    short pad3;
#endif sun
};

struct descr_f						/* for the notesfile: */
{
    long    d_format;					/* nf's format */
    char    d_title[NNLEN];				/* nf's name */
    char    d_drmes[DMLEN];				/* director message */
    short   d_plcy;					/* ==0 if no message */
#ifdef sun
    short pad1;
#endif sun
    struct when_f   d_lastm;				/* last modified time */
    short   d_stat;					/* open/closed/etc */
    short   d_nnote;					/* how many notes in file */
    struct id_f d_id;					/* sys name & unique id counter */
    struct when_f   d_lstxmit;				/* last network transmit */
    struct when_f   d_created;				/* creation date */
    struct when_f   d_lastuse;				/* last day used */
    long    d_daysused;					/* count those days */
    long    d_rspwrit;					/* number of responses ever written */
    long    d_notwrit;					/* number of notes ever written */
    long    entries;					/* number of entries into the notefile */
    long    walltime;					/* man-seconds (?) spent in notefile */
    long    d_rspread;					/* number of responses read */
    long    d_notread;					/* and number of notes */
    long    d_rsprcvd;					/* network in stats */
    long    d_notrcvd;
    long    d_rspxmit;					/* network out stats */
    long    d_notxmit;
    long    d_notdrop;					/* duplicate notes recieved */
    long    d_rspdrop;					/* and dropped on ground */
    long    d_orphans;					/* orphaned responses */
    long    netwrkouts;					/* number of times networked out */
    long    netwrkins;					/* and number of networked in */
    short   d_nfnum;					/* unique to this notesfile */
#ifdef sun
    short   pad2;
#endif sun
    long    d_archtime;					/* archive after X days */
    long    d_workset;					/* working set size */
    long    d_delnote;					/* count deletes */
    long    d_delresp;					/* count resp dels */
    long    d_dmesgstat;				/* use dirmsg for archive */
    long    d_archkeep;					/* keep/delete */
    long    d_adopted;					/* orphans adopted */
    long    d_longnote;					/* max per article */
    char    d_filler[20];				/* future use ... */
};

struct io_f						/* master i/o form */
{
    int     fidtxt;					/* text */
    int     fidndx;					/* note.indx */
    int     fidrdx;					/* resp.indx */
    struct descr_f  descr;				/* current descr */
							/* updated by critical sections */
    char    nf[NNLEN];					/* last part of name */
    char    basedir[WDLEN];				/* its directory */
    char    fullname[WDLEN];				/* full pathname */
    char    xstring[TITLEN + 1];			/* search string */
    char    xauthor[NAMESZ + SYSSZ + 2];		/* author search */
							/* site!user\0 */
#ifdef sun
    char pad2;
#endif sun
    struct when_f   stime;				/* read notes/responses more recent than this */
    short   access;					/* what sort of access user has */
#ifdef sun
    int     pad1;
#endif sun
    int     nrspwrit;					/* number of responses written this entry */
    int     nnotwrit;					/* num of notes written */
    long    entered;					/* when started so can figure time in */
    int     nrspread;					/* how many responses he read */
    int     nnotread;					/* how many notes he read */
							/* num read may be tough */
    int     nnotxmit;					/* network out stats */
    int     nrspxmit;
    int     nnotrcvd;					/* network in stats */
    int     nrsprcvd;
    int     nnotdrop;					/* duplicates rom the network */
    int     nrspdrop;
    int     norphans;					/* orphans rcvd */
    int     adopted;					/* adoptions handled */
};

struct seq_f						/* sequencer entry list form */
{
    char    nfname[NNLEN];				/* name of notefile */
    struct when_f   lastin;				/* last entry time */
};

struct nflist_f						/* nf's to scan */
{
    char   *nf_name;
    short   nf_active;					/* !'ed or not */
    short   nf_seqmode;					/* sequencer mode */
};

/*
 *	Declare global variables. The actual instantiation of these 
 *	variables is in the file startup.c
 *
 */

extern char *hised;					/* preferred editor */
extern char *hisshell;					/* preferred shell */
extern char *hispager;					/* paging program */
extern char *hismailer;					/* mail program */
extern int  nrows;					/* rows on screen */
extern int  ncols;					/* screen width */
extern char *histty;					/* tty on command */
extern int  intflag;					/* DEL hit recently */
extern int  globuid;					/* his true user id */
extern int  Notesuid;					/* who's god */
extern int  Anonuid;					/* who's not allowed */
extern int  Nindex;					/* index page rows */
extern int  ignoresigs;					/* critical section */
extern char *Mstdir;					/* default nf place */
extern char *System;					/* point to it */
extern char *Authsystem;				/* author's system */
extern char *Invokedas;					/* argv[0] */
extern char Seqname[];					/* sequencing name */
extern struct when_f    Basetime;			/* zero time */

/*
 *	Various definitions that help keep things portable.
 *	Types that various functions return, etc.
 */

#if	defined(USG)
extern char *strchr ();					/* UNIX4.0 index() */
extern char *strrchr ();				/* UNIX4.0 rindex() */
#else
extern char *index ();					/* for lint */
extern char *rindex ();
#endif	defined(USG)

/*
 *	Standard library routines that return other than "int".
 */

extern int  errno;					/* syscall errors */
extern char *sys_errlist[];				/* errno messages */
extern int  sys_nerr;					/* and how many */
char   *sprintf ();					/* satisfy lint */
char   *getenv ();
long    lseek ();					/* for lint */

/*
 *	routines in the notesfile system that return other than
 *	"int".
 */

extern char *strsave ();				/* in misc.c */
extern struct nflist_f *nextgroup ();			/* in expand.c */
extern long pagein ();					/* in pagein.c */
extern long gettext ();					/* in gtext.c */
extern long puttrec ();					/* in recsio.c */