From: RHEA::DECWRL::"decvax!minow" 19-DEC-1984 22:13 To: decwrl!rhea!rex!minow Received: from DECWRL by DEC-RHEA with SMTP; Wed, 19 Dec 84 19:06-PST Received: by decwrl.ARPA (4.22.01/4.7.34) id AA19144; Wed, 19 Dec 84 19:08:25 pst Received: by decvax.UUCP (4.12/1.0) id AA06288; Wed, 19 Dec 84 21:35:52 est Date: Wed, 19 Dec 84 21:35:52 est Return-Path: Message-Id: <8412200235.AA06288@decvax.UUCP> From seismo!cmcl2!hipl!tony Thu Sep 20 13:04:13 1984 Received: by decvax.UUCP (4.12/1.0) id AA12419; Thu, 20 Sep 84 13:03:10 edt Received: from cmcl2.UUCP by seismo.ARPA with UUCP; Thu, 20 Sep 84 12:21:56 EDT Received: by NYU-CMCL2.ARPA; Thu, 20 Sep 84 12:08:11 edt Received: by hipl.UUCP (4.12/4.7) id AA04456; Thu, 20 Sep 84 11:54:15 edt Date: Thu, 20 Sep 84 11:54:15 edt From: seismo!cmcl2!hipl!tony (Tony Movshon) Message-Id: <8409201554.AA04456@hipl.UUCP> To: minow@decvax Status: R Martin: Some more Decus C stuff. (If you want me to stop sending you this kind of thing, say so). This file is a nested archive containing: Two things for your miscellany: a rudimentary mail system for TSX-Plus and a build program (alternative to BUILD). A bug-fix for comm.c, in the form of the function equals(). Cut at the end of this message, extract with archx, then inspect the results. Tony Movshon PS: Thanks for ASCR50.MAC ... PPS: I have minor adaptations of archx and archc that run under MSDOS using the Lattice compiler. Any interest? -h- mail.arc Thu Sep 20 11:46:09 1984 mail.arc A simple mail system for TSX-Plus, for Decus C ------------------------Cut here and extract with archx---------------------- --h- mail.c Thu Sep 20 11:30:29 1984 mail.c /* * mail.c * * Mail service for TSX-Plus. * * Syntax: mail Reads mail * mail 0 Checks for the existence of mail * mail uid Sends mail where uid is a project-programmer * number or a user-name * */ /* Dox not in Runoff format ... */ #ifdef DOCUMENTATION MAIL utility for TSX-Plus MAIL is a C program that provides an inter-user mail service for users of the TSX-Plus operating system, version 4 or later. The MAIL program has three functions -- to send mail to a user, to read mail, and to check for the existence of mail. 1. To send mail to another user, type "MAIL name", where name is the addressee's user name; you may also use the project,programmer number instead of the user name. The mail program will then accept a typed message and append it to any other existing messages waiting for that user. The mail program automatically heads your message with your identity and with the date and time. To terminate the message, type control-Z. You may of course send mail to yourself. You may also use the contents of a file in place of the typed message by typing mail henry username, e.g. 1,2 BOB 1,4 HENRY 99,99 SYSOPS 3. Each user's startup command file should include a "MAIL 0" command. 4. The program MAIL.SAV should be present on SY:. * * * * * Note that the mail system may only be used with project and programmer numbers in the range 1 - 999. Note also that it is possible to send mail to a project-programmer number that is not assigned to any user on the system, although user names are checked against "msg:usr.lst". The MAIL program works by creating files on device MSG: for each user to whom mail is sent. The files are unique to each user, and are of the form MSG:MAIm.n (expanded with leading zeroes, e.g. MSG:MAI003.012 is the file for user 3,12). Users may edit their message files, delete them or whatever. It is not good practice to leave old mail in the file, since the startup message "You have mail" means only that your mail file exists, not that someone has added to it since you last looked at it. * * * * * J. Anthony Movshon, Psychology Dept., NYU, New York, NY 10003 10 January 1983, revised 7 June 1984. #endif #include #include #define EOS 0 FILE *fi,*fo; char fname[16]; char myname[13]; int proj,prog; int j = -10; int k = -12; int hatc; int type; int old = 0; int skip = 0; int out = 0; long timval; char *timetext; extern char *ctime(); extern long time(); extern int call(); extern int ispy(); extern int scca(); char *$$prmt = "mail> "; char *namefile = "msg:usr.lst"; main(argc, argv) int argc; char **argv; { register c,d; proj = call(ispy,1,&j); prog = call(ispy,1,&k); call(scca,1,&hatc); type = sctype(); if (argc == 1) { typemail(); exit(); } argv++; if (**argv == '0') { chkmail(); exit(); } if (**argv == '+') { skip = atoi(*argv); typemail(); exit(); } if (isalpha(**argv)) lookup(*argv); else { if(sscanf(*argv,"%d,%d",&proj,&prog) != 2) { fprintf(stderr, "mail: don't grok \"%s\"\n",*argv); exit(); } } maknam(); if ((fo = fopen(fname,"w")) == NULL) { fprintf (stderr, "mail: can't create output %s\n", fname); exit(); } if ((fi = fopen(fname,"r")) != NULL) { old++; while ((c = getc(fi)) != EOF) putc(c,fo); } header(); if (isatty(fileno(stdin))) { printf ("Type your message, then control-Z\n"); if (freopen("tt:","run",stdin) == NULL) { fprintf(stderr,"mail: erk! can't reopen stdin\n"); exit(); } } while ((c = getchar()) != EOF) { if(isprint(c) || isspace(c) && c != '\r') putc((d=c),fo); } if (d != '\n') putc('\n',fo); if (ferror(fo) == NULL) fclose(fo); else fprintf (stderr, "mail: fatal error writing message file\n"); } maknam() { register i; sprintf(fname,"msg:mai%3d.%3d",proj,prog); for(i=0; fname[i] != EOS; i++) { if(fname[i] == ' ') fname[i] = '0'; } } lookup(name) char *name; { int prj,prg,found; char uname[20]; if ((fi = fopen(namefile,"r")) == NULL) { fprintf (stderr, "mail: can't locate system namelist %s\n",namefile); exit(); } found = 0; while (fscanf(fi,"%d,%d%s",&prj,&prg,uname) == 3) { lowers(name); lowers(uname); if (strcmp(name,uname) == NULL) { found++; proj=prj, prog=prg; fclose(fi); break; } } if (found == 0) { fprintf (stderr, "mail: can't locate user \"%s\"\n",name); exit(); } } header() { register i; proj = call(ispy,1,&j); prog = call(ispy,1,&k); getuname(myname); lowers(myname); if(old) putc('\f',fo); time(&timval); timetext = ctime(&timval); timetext[24] = '\0'; fprintf(fo, "--- Mail from %s (%d,%d), %s ---\n", myname, proj, prog, timetext); } chkmail() { maknam(); if ((fi = fopen(fname,"r")) != NULL) printf("You have mail\n"); } typemail() { register c; maknam(); if ((fi = fopen(fname,"r")) == NULL) { printf("No mail\n"); exit(); } while (skip) { if ((c = getc(fi)) == EOF) exit(); if (c == '\f') skip--; } if (type > 1) scerpg(1,1); while ((c = getc(fi)) != EOF) { if (c == '\f') { printf("\nType for more messages"); while (getchar() != '\n'); if (type > 1) scerpg(1,1); } else putchar(c); } printf("\nDelete? "); if(tolower(getchar()) == 'y') { delete(fname); printf("Mail file deleted\n"); } } lowers(string) char string[]; { register int i; for (i=0 ; string[i] != NULL ; i++ ) { if (string[i] >= 'A' && string[i] <= 'Z') string[i] |= 040; } } --h- getuna.mac Thu Sep 20 11:30:29 1984 getuna.mac ;--- tsx-plus routine to get user name ; ; getuname(string); ; char *string ; .globl getuna,csv$,cret$ .psect .prog. space= 40 getuna: jsr r5,csv$ ;cstuff mov 4(5),r4 ;point to string clrb (4) ;prepare it mov #1$,r0 ;emt argument emt 375 ;do the emt mov #2$,r3 ;point to the string 3$: movb (3)+,r2 ;get a byte cmpb r2,#space ;is it a space? beq 4$ ;yes - done movb r2,(4)+ ;no - copy a byte br 3$ ;get more 4$: clrb (4) ;zero the trailing byte clr r0 ;return zero jmp cret$ ;return 1$: .byte 0,147 .word 2$ 2$: .blkb 12. .end --h- from.c Thu Sep 20 11:30:29 1984 from.c /* * from.c * * Who is my mail from? (See mail.c for description of "mail") * */ #include #define EOS 0 FILE *fi; char fname[16]; int proj,prog; int j = -10; int k = -12; int $$narg = 1; extern int call(); extern int ispy(); main() { register c; proj = call(ispy,1,&j); prog = call(ispy,1,&k); maknam(); if ((fi = fopen(fname,"r")) == NULL) exit(); for (;;) { while ((c = getc(fi)) != EOF && c != '\n') putchar(c); putchar ('\n'); if (c == EOF) exit(); while ((c = getc(fi)) != EOF && c != '\f'); if (c == EOF) exit(); } } maknam() { register i; sprintf(fname,"msg:mai%3d.%3d",proj,prog); for(i=0; fname[i] != EOS; i++) { if(fname[i] == ' ') fname[i] = '0'; } } -h- cbld.arc Thu Sep 20 11:46:09 1984 cbld.arc An alternative to "BUILD" for compiling and linking C programs under Decus C -----------------------Cut here and extract with archx----------------------- --h- cbld.c Thu Sep 20 11:37:31 1984 cbld.c /* * cbld.c * Command file processor for DECUS C compiler * J Anthony Movshon, Dept. of Psychology, NYU * v 1.0 16-Jan-84 * v 1.1 6-Jun-84 * * usage: * cbld [-baddr][-k][-m][-n][-p] src_list [-l obj_list] * * Generates command file that compiles and links the files in src_list, * and optionally links them with the files in obj_list. * * -baddr use "addr" as base address for link (default 2000) * * -k keep .m, .s, .obj files * * -l link the following named object files * * -m generate load map * * -n compile only, do not link * * -p invoke the macro preprocessor mp for each compilation * * -x do not chain to created command file (xcc.com) */ /* Dox in format suitable for inclusion in RT-11HELP */ #ifdef DOCUMENTATION .MACRO CBLD CBLD Compile and link C programs SYNTAX cbld [-baddr][-k][-m][-n][-p][-x] src_list [-l obj_list] SEMANTICS Cbld generates and runs a command file that compiles and links a C program. Src_list is a list of C program filenames, given without the extension (which MUST be ".c"). The first file should include main(), and will be used to name the resulting .sav file. Obj_list is an optional list of object files that may be included in the link. By default, cbld links to the file "c:suport.obj", and the libraries "c:culib.obj" and "c:clib.obj". OPTIONS -baddr Pass "addr" to linker as base address (default 2000) -k Do not delete intermediate files after compilation -l Include the following object files in the link -m Produce a load map from the link -n Compile the named files only, do not link them -p Invoke the macro preprocessor mp for each compilation; this is needed only if your programs have #define statements with arguments or nested #include statements. -x Create the command file "dk:xcc.com" but do not chain to it EXAMPLES cbld prog cbld -n file1 file2 file3 cbld -b10000 -k -m -p prog -l mylib forlib .ENDM #endif #include int mp = 0; /*invoke mp*/ int link = 1; /*link after compilation*/ int linkobj = 0; /*include obj_list in link*/ int keep = 0; /*do not delete intermediate files*/ int map = 0; /*generate load map*/ int chainx = 1; /*chain to xcc.com*/ char fn[20]; /*filename buffer*/ char base[] = "002000"; /*link base address*/ char ln[10][20]; /*list of filenames for link*/ char dn[20][20]; /*list of filenames for deletion*/ char dln[10][20]; /*list of filenames for deletion if link*/ char *version = "!cbld v1.1 7-Jun-84\n"; /* version id */ char *$$prmt = "cbld> "; /* prompt if RUN */ int i = 0; /*counters*/ int j = 0; int k = 0; int l = 0; int m = 0; main(argc, argv) int argc; char *argv[]; { FILE *fp,*fopen(); if ((fp = fopen("xcc.com","w")) == NULL) { fprintf(stderr,"cbld: can't create command file"); exit(0); } fprintf(fp,"%s",version); argc--, argv++; for (i = 0 ; argc ; argc--, argv++) { if (i > 9) usage(); if (argv[0][0] == '-') { switch (argv[0][1]) { case 'b': strcpy(base,argv[0]+2); break; case 'k': keep++; break; case 'l': linkobj = 1; goto linkit; break; case 'm': map++; break; case 'n': link = 0; break; case 'p': mp++; break; case 'x': chainx = 0; break; default: usage(); break; } } else { strcpy(fn,*argv); if (mp) { fprintf(fp,"ru c:mp %s.c\n",fn,fn); fprintf(fp,"ru c:cc %s.mpc\n",fn,fn); sprintf(dn[k++],"%s.mpc",fn); } else fprintf(fp,"ru c:cc %s\n",fn,fn); sprintf(dn[k++],"%s.s",fn); fprintf(fp,"ru c:as %s\n",fn,fn); sprintf(dln[l++],"%s.obj",fn); strcpy(ln[i++],fn); } } linkit: if (linkobj) { argc--, argv++; for (; argc ; argc--, argv++) strcpy(ln[i++],*argv); } if (link || linkobj) { fprintf(fp,"link/prompt/bot:%s",base); if (map) fprintf(fp,"/map:%s",ln[0]); fprintf(fp," %s\n",ln[0]); for (j = 1 ; j < i ; j++) fprintf(fp,"%s\n",ln[j]); fprintf(fp,"c:suport,culib,clib//\n"); } fprintf(fp,"pip\n"); if (!keep) { for (m = 0 ; m < k ; m++) fprintf(fp,"%s/d\n",dn[m]); if (link) { for (m = 0 ; m < l ; m++) fprintf(fp,"%s/d\n",dln[m]); } } fprintf(fp,"xcc.com/d\n\03\n"); fclose(fp); if (chainx) chain("@xcc"); } usage() { fprintf(stderr, "Usage: cbld [-baddr][-k][-m][-n][-p][-x] src_list [-l obj_list]\n"); exit(); } --h- chain.mac Thu Sep 20 11:37:31 1984 chain.mac ; ;--- c exit routine to pass chain command string to monitor ; .globl chain,csv$ .mcall .exit jsw= 44 $chain= 4000 .psect .prog. chain: jsr r5,csv$ ;cstuff mov 4(5),r4 ;point to string mov #1000,sp ;reset stack mov #512,r1 ;store string here 1$: movb (4)+,r0 ;pass character beq 3$ ;null ends string cmpb r0,#12 ;linefeed ends line bne 2$ ;anything else goes clrb r0 ;(to make .asciz format) 2$: movb r0,(1)+ ;put string out br 1$ ;get more 3$: clrb (1)+ ;zero final byte sub #512,r1 ;compute string length mov r1,@#510 ;store it bis #$chain,@#jsw ;inform system of chain clr r0 ;make a *hard* exit .exit ;go to it .end -h- equals.c Thu Sep 20 11:46:09 1984 equals.c /* * function from comm.c with bug-fix * the error was in the "return" statement, which omitted the "*"s */ equals(str1, str2) char *str1; /* Strings */ char *str2; /* to compare */ { register char *p1; register char *p2; p1 = str1 - 1; p2 = str2 - 1; while (*++p1 == *++p2) { if (*p1 == 0) return(0); } return((*p1 < *p2) ? 1 : 2); }