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 */