1*7c478bd9Sstevel@tonic-gate /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ 2*7c478bd9Sstevel@tonic-gate /* All Rights Reserved */ 3*7c478bd9Sstevel@tonic-gate 4*7c478bd9Sstevel@tonic-gate 5*7c478bd9Sstevel@tonic-gate /* 6*7c478bd9Sstevel@tonic-gate * Copyright (c) 1980 Regents of the University of California. 7*7c478bd9Sstevel@tonic-gate * All rights reserved. The Berkeley software License Agreement 8*7c478bd9Sstevel@tonic-gate * specifies the terms and conditions for redistribution. 9*7c478bd9Sstevel@tonic-gate */ 10*7c478bd9Sstevel@tonic-gate 11*7c478bd9Sstevel@tonic-gate /* 12*7c478bd9Sstevel@tonic-gate * Copyright (c) 1983, 1984 1985, 1986, 1987, 1988, Sun Microsystems, Inc. 13*7c478bd9Sstevel@tonic-gate * All Rights Reserved. 14*7c478bd9Sstevel@tonic-gate */ 15*7c478bd9Sstevel@tonic-gate 16*7c478bd9Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 17*7c478bd9Sstevel@tonic-gate 18*7c478bd9Sstevel@tonic-gate 19*7c478bd9Sstevel@tonic-gate #include <locale.h> 20*7c478bd9Sstevel@tonic-gate #include <stdio.h> 21*7c478bd9Sstevel@tonic-gate #include <ctype.h> 22*7c478bd9Sstevel@tonic-gate #include <signal.h> 23*7c478bd9Sstevel@tonic-gate #define MAXENT 50 24*7c478bd9Sstevel@tonic-gate 25*7c478bd9Sstevel@tonic-gate struct skeleton { 26*7c478bd9Sstevel@tonic-gate char prompt[20]; /* prompt user for entry */ 27*7c478bd9Sstevel@tonic-gate char keylet[5]; /* key letter for database */ 28*7c478bd9Sstevel@tonic-gate } bibskel[MAXENT] = { 29*7c478bd9Sstevel@tonic-gate " Author:", "%A", 30*7c478bd9Sstevel@tonic-gate " Title:", "%T", 31*7c478bd9Sstevel@tonic-gate " Journal:", "%J", 32*7c478bd9Sstevel@tonic-gate " Volume:", "%V", 33*7c478bd9Sstevel@tonic-gate " Pages:", "%P", 34*7c478bd9Sstevel@tonic-gate "Publisher:", "%I", 35*7c478bd9Sstevel@tonic-gate " City:", "%C", 36*7c478bd9Sstevel@tonic-gate " Date:", "%D", 37*7c478bd9Sstevel@tonic-gate " Other:", "%O", 38*7c478bd9Sstevel@tonic-gate " Keywords:", "%K", }; 39*7c478bd9Sstevel@tonic-gate 40*7c478bd9Sstevel@tonic-gate int entries = 10; /* total number of entries in bibskel */ 41*7c478bd9Sstevel@tonic-gate int abstract = 1; /* asking for abstracts is the default */ 42*7c478bd9Sstevel@tonic-gate 43*7c478bd9Sstevel@tonic-gate usage() /* print proper usage and exit */ 44*7c478bd9Sstevel@tonic-gate { 45*7c478bd9Sstevel@tonic-gate puts(gettext("Usage: addbib [-p promptfile] [-a] database\n\ 46*7c478bd9Sstevel@tonic-gate \t-p: the promptfile defines alternate fields\n\ 47*7c478bd9Sstevel@tonic-gate \t-a: don't include prompting for the abstract\n")); 48*7c478bd9Sstevel@tonic-gate exit(1); 49*7c478bd9Sstevel@tonic-gate } 50*7c478bd9Sstevel@tonic-gate 51*7c478bd9Sstevel@tonic-gate main(argc, argv) /* addbib: bibliography entry program */ 52*7c478bd9Sstevel@tonic-gate int argc; 53*7c478bd9Sstevel@tonic-gate char *argv[]; 54*7c478bd9Sstevel@tonic-gate { 55*7c478bd9Sstevel@tonic-gate FILE *fp, *fopen(); 56*7c478bd9Sstevel@tonic-gate int i; 57*7c478bd9Sstevel@tonic-gate 58*7c478bd9Sstevel@tonic-gate (void) setlocale(LC_ALL, ""); 59*7c478bd9Sstevel@tonic-gate 60*7c478bd9Sstevel@tonic-gate #if !defined(TEXT_DOMAIN) 61*7c478bd9Sstevel@tonic-gate #define TEXT_DOMAIN "SYS_TEST" 62*7c478bd9Sstevel@tonic-gate #endif 63*7c478bd9Sstevel@tonic-gate (void) textdomain(TEXT_DOMAIN); 64*7c478bd9Sstevel@tonic-gate 65*7c478bd9Sstevel@tonic-gate if (argc == 1) 66*7c478bd9Sstevel@tonic-gate { 67*7c478bd9Sstevel@tonic-gate puts(gettext("You must specify a bibliography file (database).")); 68*7c478bd9Sstevel@tonic-gate usage(); 69*7c478bd9Sstevel@tonic-gate } 70*7c478bd9Sstevel@tonic-gate for (i = 1; argv[i][0] == '-'; i++) 71*7c478bd9Sstevel@tonic-gate { 72*7c478bd9Sstevel@tonic-gate if (argv[i][1] == 'p') 73*7c478bd9Sstevel@tonic-gate { 74*7c478bd9Sstevel@tonic-gate if (i >= argc - 2) 75*7c478bd9Sstevel@tonic-gate { 76*7c478bd9Sstevel@tonic-gate puts(gettext("Not enough arguments for -p option.")); 77*7c478bd9Sstevel@tonic-gate usage(); 78*7c478bd9Sstevel@tonic-gate } 79*7c478bd9Sstevel@tonic-gate rd_skel(argv[++i]); 80*7c478bd9Sstevel@tonic-gate } 81*7c478bd9Sstevel@tonic-gate else if (argv[i][1] == 'a') 82*7c478bd9Sstevel@tonic-gate { 83*7c478bd9Sstevel@tonic-gate if (i >= argc - 1) 84*7c478bd9Sstevel@tonic-gate { 85*7c478bd9Sstevel@tonic-gate puts(gettext("No bibliofile specified after -a.")); 86*7c478bd9Sstevel@tonic-gate usage(); 87*7c478bd9Sstevel@tonic-gate } 88*7c478bd9Sstevel@tonic-gate abstract = 0; 89*7c478bd9Sstevel@tonic-gate } 90*7c478bd9Sstevel@tonic-gate else /* neither -p nor -a */ 91*7c478bd9Sstevel@tonic-gate { 92*7c478bd9Sstevel@tonic-gate printf(gettext("Invalid command line flag: %s\n"), argv[i]); 93*7c478bd9Sstevel@tonic-gate usage(); 94*7c478bd9Sstevel@tonic-gate } 95*7c478bd9Sstevel@tonic-gate } 96*7c478bd9Sstevel@tonic-gate if (i < argc - 1) 97*7c478bd9Sstevel@tonic-gate { 98*7c478bd9Sstevel@tonic-gate puts(gettext("Too many arguments with no options.")); 99*7c478bd9Sstevel@tonic-gate usage(); 100*7c478bd9Sstevel@tonic-gate } 101*7c478bd9Sstevel@tonic-gate if ((fp = fopen(argv[i], "a")) == NULL) 102*7c478bd9Sstevel@tonic-gate { 103*7c478bd9Sstevel@tonic-gate perror(argv[i]); 104*7c478bd9Sstevel@tonic-gate exit(1); 105*7c478bd9Sstevel@tonic-gate } 106*7c478bd9Sstevel@tonic-gate addbib(fp, argv[i]); /* loop for input */ 107*7c478bd9Sstevel@tonic-gate exit(0); 108*7c478bd9Sstevel@tonic-gate /* NOTREACHED */ 109*7c478bd9Sstevel@tonic-gate } 110*7c478bd9Sstevel@tonic-gate 111*7c478bd9Sstevel@tonic-gate addbib(fp, argv) /* add entries to a bibliographic database */ 112*7c478bd9Sstevel@tonic-gate FILE *fp; 113*7c478bd9Sstevel@tonic-gate char *argv; 114*7c478bd9Sstevel@tonic-gate { 115*7c478bd9Sstevel@tonic-gate char line[BUFSIZ]; 116*7c478bd9Sstevel@tonic-gate int i = 0, firstln, repeat = 0, escape = 0; 117*7c478bd9Sstevel@tonic-gate 118*7c478bd9Sstevel@tonic-gate printf(gettext("Instructions? ")); 119*7c478bd9Sstevel@tonic-gate fgets(line, BUFSIZ, stdin); 120*7c478bd9Sstevel@tonic-gate if (line[0] == 'y' || line[0] == 'Y') 121*7c478bd9Sstevel@tonic-gate instruct(); 122*7c478bd9Sstevel@tonic-gate while (1) 123*7c478bd9Sstevel@tonic-gate { 124*7c478bd9Sstevel@tonic-gate putchar('\n'); 125*7c478bd9Sstevel@tonic-gate putc('\n', fp); 126*7c478bd9Sstevel@tonic-gate for (i = 0; i < entries; i++) 127*7c478bd9Sstevel@tonic-gate { 128*7c478bd9Sstevel@tonic-gate printf("%s\t", gettext(bibskel[i].prompt)); 129*7c478bd9Sstevel@tonic-gate if (fgets(line, BUFSIZ, stdin) == NULL) 130*7c478bd9Sstevel@tonic-gate { 131*7c478bd9Sstevel@tonic-gate clearerr(stdin); 132*7c478bd9Sstevel@tonic-gate break; 133*7c478bd9Sstevel@tonic-gate } 134*7c478bd9Sstevel@tonic-gate if (line[0] == '-' && line[1] == '\n') 135*7c478bd9Sstevel@tonic-gate { 136*7c478bd9Sstevel@tonic-gate i -= 2; 137*7c478bd9Sstevel@tonic-gate if (i < -1) 138*7c478bd9Sstevel@tonic-gate { 139*7c478bd9Sstevel@tonic-gate printf(gettext("Too far back.\n")); 140*7c478bd9Sstevel@tonic-gate i++; 141*7c478bd9Sstevel@tonic-gate } 142*7c478bd9Sstevel@tonic-gate continue; 143*7c478bd9Sstevel@tonic-gate } 144*7c478bd9Sstevel@tonic-gate else if (line[strlen(line)-2] == '\\') 145*7c478bd9Sstevel@tonic-gate { 146*7c478bd9Sstevel@tonic-gate if (line[0] != '\\') 147*7c478bd9Sstevel@tonic-gate { 148*7c478bd9Sstevel@tonic-gate line[strlen(line)-2] = '\n'; 149*7c478bd9Sstevel@tonic-gate line[strlen(line)-1] = NULL; 150*7c478bd9Sstevel@tonic-gate trim(line); 151*7c478bd9Sstevel@tonic-gate fprintf(fp, "%s %s", 152*7c478bd9Sstevel@tonic-gate bibskel[i].keylet, line); 153*7c478bd9Sstevel@tonic-gate } 154*7c478bd9Sstevel@tonic-gate printf("> "); 155*7c478bd9Sstevel@tonic-gate again: 156*7c478bd9Sstevel@tonic-gate fgets(line, BUFSIZ, stdin); 157*7c478bd9Sstevel@tonic-gate if (line[strlen(line)-2] == '\\') 158*7c478bd9Sstevel@tonic-gate { 159*7c478bd9Sstevel@tonic-gate line[strlen(line)-2] = '\n'; 160*7c478bd9Sstevel@tonic-gate line[strlen(line)-1] = NULL; 161*7c478bd9Sstevel@tonic-gate trim(line); 162*7c478bd9Sstevel@tonic-gate fputs(line, fp); 163*7c478bd9Sstevel@tonic-gate printf("> "); 164*7c478bd9Sstevel@tonic-gate goto again; 165*7c478bd9Sstevel@tonic-gate } 166*7c478bd9Sstevel@tonic-gate trim(line); 167*7c478bd9Sstevel@tonic-gate fputs(line, fp); 168*7c478bd9Sstevel@tonic-gate } 169*7c478bd9Sstevel@tonic-gate else if (line[0] != '\n') 170*7c478bd9Sstevel@tonic-gate { 171*7c478bd9Sstevel@tonic-gate trim(line); 172*7c478bd9Sstevel@tonic-gate fprintf(fp, "%s %s", bibskel[i].keylet, line); 173*7c478bd9Sstevel@tonic-gate } 174*7c478bd9Sstevel@tonic-gate } 175*7c478bd9Sstevel@tonic-gate if (abstract) 176*7c478bd9Sstevel@tonic-gate { 177*7c478bd9Sstevel@tonic-gate puts(gettext(" Abstract: (ctrl-d to end)")); 178*7c478bd9Sstevel@tonic-gate firstln = 1; 179*7c478bd9Sstevel@tonic-gate while (fgets(line, BUFSIZ, stdin)) 180*7c478bd9Sstevel@tonic-gate { 181*7c478bd9Sstevel@tonic-gate if (firstln && line[0] != '%') 182*7c478bd9Sstevel@tonic-gate { 183*7c478bd9Sstevel@tonic-gate fprintf(fp, "%%X "); 184*7c478bd9Sstevel@tonic-gate firstln = 0; 185*7c478bd9Sstevel@tonic-gate } 186*7c478bd9Sstevel@tonic-gate fputs(line, fp); 187*7c478bd9Sstevel@tonic-gate } 188*7c478bd9Sstevel@tonic-gate clearerr(stdin); 189*7c478bd9Sstevel@tonic-gate } 190*7c478bd9Sstevel@tonic-gate fflush(fp); /* write to file at end of each cycle */ 191*7c478bd9Sstevel@tonic-gate if (ferror(fp)) 192*7c478bd9Sstevel@tonic-gate { 193*7c478bd9Sstevel@tonic-gate perror(argv); 194*7c478bd9Sstevel@tonic-gate exit(1); 195*7c478bd9Sstevel@tonic-gate } 196*7c478bd9Sstevel@tonic-gate editloop: 197*7c478bd9Sstevel@tonic-gate printf(gettext("\nContinue? ")); 198*7c478bd9Sstevel@tonic-gate fgets(line, BUFSIZ, stdin); 199*7c478bd9Sstevel@tonic-gate if (line[0] == 'e' || line[0] == 'v') 200*7c478bd9Sstevel@tonic-gate { 201*7c478bd9Sstevel@tonic-gate bibedit(fp, line, argv); 202*7c478bd9Sstevel@tonic-gate goto editloop; 203*7c478bd9Sstevel@tonic-gate } 204*7c478bd9Sstevel@tonic-gate if (line[0] == 'q' || line[0] == 'n') 205*7c478bd9Sstevel@tonic-gate return; 206*7c478bd9Sstevel@tonic-gate } 207*7c478bd9Sstevel@tonic-gate } 208*7c478bd9Sstevel@tonic-gate 209*7c478bd9Sstevel@tonic-gate trim(line) /* trim line of trailing white space */ 210*7c478bd9Sstevel@tonic-gate char line[]; 211*7c478bd9Sstevel@tonic-gate { 212*7c478bd9Sstevel@tonic-gate int n; 213*7c478bd9Sstevel@tonic-gate 214*7c478bd9Sstevel@tonic-gate n = strlen(line); 215*7c478bd9Sstevel@tonic-gate while (--n >= 0) 216*7c478bd9Sstevel@tonic-gate { 217*7c478bd9Sstevel@tonic-gate if (!isspace(line[n])) 218*7c478bd9Sstevel@tonic-gate break; 219*7c478bd9Sstevel@tonic-gate } 220*7c478bd9Sstevel@tonic-gate line[++n] = '\n'; 221*7c478bd9Sstevel@tonic-gate line[++n] = NULL; 222*7c478bd9Sstevel@tonic-gate } 223*7c478bd9Sstevel@tonic-gate 224*7c478bd9Sstevel@tonic-gate bibedit(fp, cmd, arg) /* edit database with edit, ex, or vi */ 225*7c478bd9Sstevel@tonic-gate FILE *fp; 226*7c478bd9Sstevel@tonic-gate char *cmd, *arg; 227*7c478bd9Sstevel@tonic-gate { 228*7c478bd9Sstevel@tonic-gate int i = 0, status; 229*7c478bd9Sstevel@tonic-gate 230*7c478bd9Sstevel@tonic-gate fclose(fp); 231*7c478bd9Sstevel@tonic-gate while (!isspace(cmd[i])) 232*7c478bd9Sstevel@tonic-gate i++; 233*7c478bd9Sstevel@tonic-gate cmd[i] = NULL; 234*7c478bd9Sstevel@tonic-gate if (fork() == 0) 235*7c478bd9Sstevel@tonic-gate { 236*7c478bd9Sstevel@tonic-gate if (cmd[0] == 'v' && cmd[1] == 'i') 237*7c478bd9Sstevel@tonic-gate execlp(cmd, cmd, "+$", arg, NULL); 238*7c478bd9Sstevel@tonic-gate else /* either ed, ex, or edit */ 239*7c478bd9Sstevel@tonic-gate execlp(cmd, cmd, arg, NULL); 240*7c478bd9Sstevel@tonic-gate } 241*7c478bd9Sstevel@tonic-gate signal(SIGINT, SIG_IGN); 242*7c478bd9Sstevel@tonic-gate signal(SIGQUIT, SIG_IGN); 243*7c478bd9Sstevel@tonic-gate wait(&status); 244*7c478bd9Sstevel@tonic-gate signal(SIGINT, SIG_DFL); 245*7c478bd9Sstevel@tonic-gate signal(SIGQUIT, SIG_DFL); 246*7c478bd9Sstevel@tonic-gate if ((fp = fopen(arg, "a")) == NULL) 247*7c478bd9Sstevel@tonic-gate { 248*7c478bd9Sstevel@tonic-gate perror(arg); 249*7c478bd9Sstevel@tonic-gate exit(1); 250*7c478bd9Sstevel@tonic-gate } 251*7c478bd9Sstevel@tonic-gate } 252*7c478bd9Sstevel@tonic-gate 253*7c478bd9Sstevel@tonic-gate instruct() /* give user elementary directions */ 254*7c478bd9Sstevel@tonic-gate { 255*7c478bd9Sstevel@tonic-gate putchar('\n'); 256*7c478bd9Sstevel@tonic-gate puts(gettext("Addbib will prompt you for various bibliographic fields.\n" 257*7c478bd9Sstevel@tonic-gate "If you don't need a particular field, just hit RETURN,\n" 258*7c478bd9Sstevel@tonic-gate "\tand that field will not appear in the output file.\n" 259*7c478bd9Sstevel@tonic-gate "If you want to return to previous fields in the skeleton,\n" 260*7c478bd9Sstevel@tonic-gate "\ta single minus sign will go back a field at a time.\n" 261*7c478bd9Sstevel@tonic-gate "\t(This is the best way to input multiple authors.)\n" 262*7c478bd9Sstevel@tonic-gate "If you have to continue a field or add an unusual field,\n" 263*7c478bd9Sstevel@tonic-gate "\ta trailing backslash will allow a temporary escape.\n" 264*7c478bd9Sstevel@tonic-gate "Finally, (without -a) you will be prompted for an abstract\n" 265*7c478bd9Sstevel@tonic-gate "Type in as many lines as you need, and end with a ctrl-d.\n" 266*7c478bd9Sstevel@tonic-gate "To quit, type `q' or `n' when asked if you want to continue.\n" 267*7c478bd9Sstevel@tonic-gate "To edit the database, type `edit', `vi', or `ex' instead.")); 268*7c478bd9Sstevel@tonic-gate 269*7c478bd9Sstevel@tonic-gate } 270*7c478bd9Sstevel@tonic-gate 271*7c478bd9Sstevel@tonic-gate rd_skel(arg) /* redo bibskel from user-supplied file */ 272*7c478bd9Sstevel@tonic-gate char *arg; 273*7c478bd9Sstevel@tonic-gate { 274*7c478bd9Sstevel@tonic-gate FILE *pfp, *fopen(); 275*7c478bd9Sstevel@tonic-gate char str[BUFSIZ]; 276*7c478bd9Sstevel@tonic-gate int entry, i, j; 277*7c478bd9Sstevel@tonic-gate 278*7c478bd9Sstevel@tonic-gate if ((pfp = fopen(arg, "r")) == NULL) 279*7c478bd9Sstevel@tonic-gate { 280*7c478bd9Sstevel@tonic-gate fprintf(stderr, gettext("Promptfile ")); 281*7c478bd9Sstevel@tonic-gate perror(arg); 282*7c478bd9Sstevel@tonic-gate exit(1); 283*7c478bd9Sstevel@tonic-gate } 284*7c478bd9Sstevel@tonic-gate for (entry = 0; fgets(str, BUFSIZ, pfp); entry++) 285*7c478bd9Sstevel@tonic-gate { 286*7c478bd9Sstevel@tonic-gate for (i = 0; str[i] != '\t' && str[i] != '\n'; i++) 287*7c478bd9Sstevel@tonic-gate bibskel[entry].prompt[i] = str[i]; 288*7c478bd9Sstevel@tonic-gate bibskel[entry].prompt[i] = NULL; 289*7c478bd9Sstevel@tonic-gate if (str[i] == '\n') 290*7c478bd9Sstevel@tonic-gate { 291*7c478bd9Sstevel@tonic-gate fprintf(stderr, gettext("No tabs between promptfile fields.\n")); 292*7c478bd9Sstevel@tonic-gate fprintf(stderr, gettext("Format: prompt-string <TAB> %%key\n")); 293*7c478bd9Sstevel@tonic-gate exit(1); 294*7c478bd9Sstevel@tonic-gate } 295*7c478bd9Sstevel@tonic-gate for (i++, j = 0; str[i] != '\n'; i++, j++) 296*7c478bd9Sstevel@tonic-gate bibskel[entry].keylet[j] = str[i]; 297*7c478bd9Sstevel@tonic-gate bibskel[entry].keylet[j] = NULL; 298*7c478bd9Sstevel@tonic-gate 299*7c478bd9Sstevel@tonic-gate if (entry >= MAXENT) 300*7c478bd9Sstevel@tonic-gate { 301*7c478bd9Sstevel@tonic-gate fprintf(stderr, gettext("Too many entries in promptfile.\n")); 302*7c478bd9Sstevel@tonic-gate exit(1); 303*7c478bd9Sstevel@tonic-gate } 304*7c478bd9Sstevel@tonic-gate } 305*7c478bd9Sstevel@tonic-gate entries = entry; 306*7c478bd9Sstevel@tonic-gate fclose(pfp); 307*7c478bd9Sstevel@tonic-gate } 308