1*11a8fa6cSceastha /* 2*11a8fa6cSceastha * Copyright 2005 Sun Microsystems, Inc. All rights reserved. 3*11a8fa6cSceastha * Use is subject to license terms. 4*11a8fa6cSceastha */ 5*11a8fa6cSceastha 67c478bd9Sstevel@tonic-gate /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ 77c478bd9Sstevel@tonic-gate /* All Rights Reserved */ 87c478bd9Sstevel@tonic-gate 97c478bd9Sstevel@tonic-gate /* 107c478bd9Sstevel@tonic-gate * Copyright (c) 1980 Regents of the University of California. 117c478bd9Sstevel@tonic-gate * All rights reserved. The Berkeley software License Agreement 127c478bd9Sstevel@tonic-gate * specifies the terms and conditions for redistribution. 137c478bd9Sstevel@tonic-gate */ 147c478bd9Sstevel@tonic-gate 157c478bd9Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 167c478bd9Sstevel@tonic-gate 177c478bd9Sstevel@tonic-gate 187c478bd9Sstevel@tonic-gate #include <locale.h> 197c478bd9Sstevel@tonic-gate #include <stdio.h> 207c478bd9Sstevel@tonic-gate #include <ctype.h> 217c478bd9Sstevel@tonic-gate #include <signal.h> 227c478bd9Sstevel@tonic-gate #define MAXENT 50 237c478bd9Sstevel@tonic-gate 247c478bd9Sstevel@tonic-gate struct skeleton { 257c478bd9Sstevel@tonic-gate char prompt[20]; /* prompt user for entry */ 267c478bd9Sstevel@tonic-gate char keylet[5]; /* key letter for database */ 277c478bd9Sstevel@tonic-gate } bibskel[MAXENT] = { 287c478bd9Sstevel@tonic-gate " Author:", "%A", 297c478bd9Sstevel@tonic-gate " Title:", "%T", 307c478bd9Sstevel@tonic-gate " Journal:", "%J", 317c478bd9Sstevel@tonic-gate " Volume:", "%V", 327c478bd9Sstevel@tonic-gate " Pages:", "%P", 337c478bd9Sstevel@tonic-gate "Publisher:", "%I", 347c478bd9Sstevel@tonic-gate " City:", "%C", 357c478bd9Sstevel@tonic-gate " Date:", "%D", 367c478bd9Sstevel@tonic-gate " Other:", "%O", 377c478bd9Sstevel@tonic-gate " Keywords:", "%K", }; 387c478bd9Sstevel@tonic-gate 397c478bd9Sstevel@tonic-gate int entries = 10; /* total number of entries in bibskel */ 407c478bd9Sstevel@tonic-gate int abstract = 1; /* asking for abstracts is the default */ 417c478bd9Sstevel@tonic-gate 42*11a8fa6cSceastha static void addbib(FILE *, char *); 43*11a8fa6cSceastha void bibedit(FILE *, char *, char *); 44*11a8fa6cSceastha static void instruct(void); 45*11a8fa6cSceastha static void rd_skel(char *); 46*11a8fa6cSceastha static void trim(char []); 47*11a8fa6cSceastha 48*11a8fa6cSceastha static void 49*11a8fa6cSceastha usage(void) /* print proper usage and exit */ 507c478bd9Sstevel@tonic-gate { 517c478bd9Sstevel@tonic-gate puts(gettext("Usage: addbib [-p promptfile] [-a] database\n\ 527c478bd9Sstevel@tonic-gate \t-p: the promptfile defines alternate fields\n\ 537c478bd9Sstevel@tonic-gate \t-a: don't include prompting for the abstract\n")); 547c478bd9Sstevel@tonic-gate exit(1); 557c478bd9Sstevel@tonic-gate } 567c478bd9Sstevel@tonic-gate 57*11a8fa6cSceastha int 58*11a8fa6cSceastha main(int argc, char *argv[]) /* addbib: bibliography entry program */ 597c478bd9Sstevel@tonic-gate { 607c478bd9Sstevel@tonic-gate FILE *fp, *fopen(); 617c478bd9Sstevel@tonic-gate int i; 627c478bd9Sstevel@tonic-gate 637c478bd9Sstevel@tonic-gate (void) setlocale(LC_ALL, ""); 647c478bd9Sstevel@tonic-gate 657c478bd9Sstevel@tonic-gate #if !defined(TEXT_DOMAIN) 667c478bd9Sstevel@tonic-gate #define TEXT_DOMAIN "SYS_TEST" 677c478bd9Sstevel@tonic-gate #endif 687c478bd9Sstevel@tonic-gate (void) textdomain(TEXT_DOMAIN); 697c478bd9Sstevel@tonic-gate 70*11a8fa6cSceastha if (argc == 1) { 71*11a8fa6cSceastha puts(gettext( 72*11a8fa6cSceastha "You must specify a bibliography file (database).")); 737c478bd9Sstevel@tonic-gate usage(); 747c478bd9Sstevel@tonic-gate } 75*11a8fa6cSceastha for (i = 1; argv[i][0] == '-'; i++) { 76*11a8fa6cSceastha if (argv[i][1] == 'p') { 77*11a8fa6cSceastha if (i >= argc - 2) { 78*11a8fa6cSceastha puts(gettext("Not enough arguments for " 79*11a8fa6cSceastha "-p option.")); 807c478bd9Sstevel@tonic-gate usage(); 817c478bd9Sstevel@tonic-gate } 827c478bd9Sstevel@tonic-gate rd_skel(argv[++i]); 83*11a8fa6cSceastha } else if (argv[i][1] == 'a') { 84*11a8fa6cSceastha if (i >= argc - 1) { 85*11a8fa6cSceastha puts(gettext( 86*11a8fa6cSceastha "No bibliofile specified after -a.")); 877c478bd9Sstevel@tonic-gate usage(); 887c478bd9Sstevel@tonic-gate } 897c478bd9Sstevel@tonic-gate abstract = 0; 90*11a8fa6cSceastha } else { /* neither -p nor -a */ 91*11a8fa6cSceastha printf(gettext( 92*11a8fa6cSceastha "Invalid command line flag: %s\n"), argv[i]); 937c478bd9Sstevel@tonic-gate usage(); 947c478bd9Sstevel@tonic-gate } 957c478bd9Sstevel@tonic-gate } 96*11a8fa6cSceastha if (i < argc - 1) { 977c478bd9Sstevel@tonic-gate puts(gettext("Too many arguments with no options.")); 987c478bd9Sstevel@tonic-gate usage(); 997c478bd9Sstevel@tonic-gate } 100*11a8fa6cSceastha if ((fp = fopen(argv[i], "a")) == NULL) { 1017c478bd9Sstevel@tonic-gate perror(argv[i]); 1027c478bd9Sstevel@tonic-gate exit(1); 1037c478bd9Sstevel@tonic-gate } 1047c478bd9Sstevel@tonic-gate addbib(fp, argv[i]); /* loop for input */ 105*11a8fa6cSceastha return (0); 1067c478bd9Sstevel@tonic-gate } 1077c478bd9Sstevel@tonic-gate 108*11a8fa6cSceastha static void 109*11a8fa6cSceastha addbib(FILE *fp, char *argv) /* add entries to a bibliographic database */ 1107c478bd9Sstevel@tonic-gate { 1117c478bd9Sstevel@tonic-gate char line[BUFSIZ]; 1127c478bd9Sstevel@tonic-gate int i = 0, firstln, repeat = 0, escape = 0; 1137c478bd9Sstevel@tonic-gate 1147c478bd9Sstevel@tonic-gate printf(gettext("Instructions? ")); 1157c478bd9Sstevel@tonic-gate fgets(line, BUFSIZ, stdin); 1167c478bd9Sstevel@tonic-gate if (line[0] == 'y' || line[0] == 'Y') 1177c478bd9Sstevel@tonic-gate instruct(); 118*11a8fa6cSceastha while (1) { 1197c478bd9Sstevel@tonic-gate putchar('\n'); 1207c478bd9Sstevel@tonic-gate putc('\n', fp); 121*11a8fa6cSceastha for (i = 0; i < entries; i++) { 1227c478bd9Sstevel@tonic-gate printf("%s\t", gettext(bibskel[i].prompt)); 123*11a8fa6cSceastha if (fgets(line, BUFSIZ, stdin) == NULL) { 1247c478bd9Sstevel@tonic-gate clearerr(stdin); 1257c478bd9Sstevel@tonic-gate break; 1267c478bd9Sstevel@tonic-gate } 127*11a8fa6cSceastha if (line[0] == '-' && line[1] == '\n') { 1287c478bd9Sstevel@tonic-gate i -= 2; 129*11a8fa6cSceastha if (i < -1) { 1307c478bd9Sstevel@tonic-gate printf(gettext("Too far back.\n")); 1317c478bd9Sstevel@tonic-gate i++; 1327c478bd9Sstevel@tonic-gate } 1337c478bd9Sstevel@tonic-gate continue; 134*11a8fa6cSceastha } else if (line[strlen(line)-2] == '\\') { 135*11a8fa6cSceastha if (line[0] != '\\') { 1367c478bd9Sstevel@tonic-gate line[strlen(line)-2] = '\n'; 1377c478bd9Sstevel@tonic-gate line[strlen(line)-1] = NULL; 1387c478bd9Sstevel@tonic-gate trim(line); 1397c478bd9Sstevel@tonic-gate fprintf(fp, "%s %s", 1407c478bd9Sstevel@tonic-gate bibskel[i].keylet, line); 1417c478bd9Sstevel@tonic-gate } 1427c478bd9Sstevel@tonic-gate printf("> "); 1437c478bd9Sstevel@tonic-gate again: 1447c478bd9Sstevel@tonic-gate fgets(line, BUFSIZ, stdin); 145*11a8fa6cSceastha if (line[strlen(line)-2] == '\\') { 1467c478bd9Sstevel@tonic-gate line[strlen(line)-2] = '\n'; 1477c478bd9Sstevel@tonic-gate line[strlen(line)-1] = NULL; 1487c478bd9Sstevel@tonic-gate trim(line); 1497c478bd9Sstevel@tonic-gate fputs(line, fp); 1507c478bd9Sstevel@tonic-gate printf("> "); 1517c478bd9Sstevel@tonic-gate goto again; 1527c478bd9Sstevel@tonic-gate } 1537c478bd9Sstevel@tonic-gate trim(line); 1547c478bd9Sstevel@tonic-gate fputs(line, fp); 155*11a8fa6cSceastha } else if (line[0] != '\n') { 1567c478bd9Sstevel@tonic-gate trim(line); 1577c478bd9Sstevel@tonic-gate fprintf(fp, "%s %s", bibskel[i].keylet, line); 1587c478bd9Sstevel@tonic-gate } 1597c478bd9Sstevel@tonic-gate } 160*11a8fa6cSceastha if (abstract) { 1617c478bd9Sstevel@tonic-gate puts(gettext(" Abstract: (ctrl-d to end)")); 1627c478bd9Sstevel@tonic-gate firstln = 1; 163*11a8fa6cSceastha while (fgets(line, BUFSIZ, stdin)) { 164*11a8fa6cSceastha if (firstln && line[0] != '%') { 1657c478bd9Sstevel@tonic-gate fprintf(fp, "%%X "); 1667c478bd9Sstevel@tonic-gate firstln = 0; 1677c478bd9Sstevel@tonic-gate } 1687c478bd9Sstevel@tonic-gate fputs(line, fp); 1697c478bd9Sstevel@tonic-gate } 1707c478bd9Sstevel@tonic-gate clearerr(stdin); 1717c478bd9Sstevel@tonic-gate } 1727c478bd9Sstevel@tonic-gate fflush(fp); /* write to file at end of each cycle */ 173*11a8fa6cSceastha if (ferror(fp)) { 1747c478bd9Sstevel@tonic-gate perror(argv); 1757c478bd9Sstevel@tonic-gate exit(1); 1767c478bd9Sstevel@tonic-gate } 1777c478bd9Sstevel@tonic-gate editloop: 1787c478bd9Sstevel@tonic-gate printf(gettext("\nContinue? ")); 1797c478bd9Sstevel@tonic-gate fgets(line, BUFSIZ, stdin); 180*11a8fa6cSceastha if (line[0] == 'e' || line[0] == 'v') { 1817c478bd9Sstevel@tonic-gate bibedit(fp, line, argv); 1827c478bd9Sstevel@tonic-gate goto editloop; 1837c478bd9Sstevel@tonic-gate } 1847c478bd9Sstevel@tonic-gate if (line[0] == 'q' || line[0] == 'n') 1857c478bd9Sstevel@tonic-gate return; 1867c478bd9Sstevel@tonic-gate } 1877c478bd9Sstevel@tonic-gate } 1887c478bd9Sstevel@tonic-gate 189*11a8fa6cSceastha static void 190*11a8fa6cSceastha trim(char line[]) /* trim line of trailing white space */ 1917c478bd9Sstevel@tonic-gate { 1927c478bd9Sstevel@tonic-gate int n; 1937c478bd9Sstevel@tonic-gate 1947c478bd9Sstevel@tonic-gate n = strlen(line); 195*11a8fa6cSceastha while (--n >= 0) { 1967c478bd9Sstevel@tonic-gate if (!isspace(line[n])) 1977c478bd9Sstevel@tonic-gate break; 1987c478bd9Sstevel@tonic-gate } 1997c478bd9Sstevel@tonic-gate line[++n] = '\n'; 2007c478bd9Sstevel@tonic-gate line[++n] = NULL; 2017c478bd9Sstevel@tonic-gate } 2027c478bd9Sstevel@tonic-gate 203*11a8fa6cSceastha void 204*11a8fa6cSceastha bibedit(FILE *fp, char *cmd, char *arg) /* edit database with edit, ex, or vi */ 2057c478bd9Sstevel@tonic-gate { 2067c478bd9Sstevel@tonic-gate int i = 0, status; 2077c478bd9Sstevel@tonic-gate 2087c478bd9Sstevel@tonic-gate fclose(fp); 2097c478bd9Sstevel@tonic-gate while (!isspace(cmd[i])) 2107c478bd9Sstevel@tonic-gate i++; 2117c478bd9Sstevel@tonic-gate cmd[i] = NULL; 212*11a8fa6cSceastha if (fork() == 0) { 2137c478bd9Sstevel@tonic-gate if (cmd[0] == 'v' && cmd[1] == 'i') 2147c478bd9Sstevel@tonic-gate execlp(cmd, cmd, "+$", arg, NULL); 2157c478bd9Sstevel@tonic-gate else /* either ed, ex, or edit */ 2167c478bd9Sstevel@tonic-gate execlp(cmd, cmd, arg, NULL); 2177c478bd9Sstevel@tonic-gate } 2187c478bd9Sstevel@tonic-gate signal(SIGINT, SIG_IGN); 2197c478bd9Sstevel@tonic-gate signal(SIGQUIT, SIG_IGN); 2207c478bd9Sstevel@tonic-gate wait(&status); 2217c478bd9Sstevel@tonic-gate signal(SIGINT, SIG_DFL); 2227c478bd9Sstevel@tonic-gate signal(SIGQUIT, SIG_DFL); 223*11a8fa6cSceastha if ((fp = fopen(arg, "a")) == NULL) { 2247c478bd9Sstevel@tonic-gate perror(arg); 2257c478bd9Sstevel@tonic-gate exit(1); 2267c478bd9Sstevel@tonic-gate } 2277c478bd9Sstevel@tonic-gate } 2287c478bd9Sstevel@tonic-gate 229*11a8fa6cSceastha static void 230*11a8fa6cSceastha instruct(void) /* give user elementary directions */ 2317c478bd9Sstevel@tonic-gate { 2327c478bd9Sstevel@tonic-gate putchar('\n'); 233*11a8fa6cSceastha puts(gettext( 234*11a8fa6cSceastha "Addbib will prompt you for various bibliographic fields.\n" 2357c478bd9Sstevel@tonic-gate "If you don't need a particular field, just hit RETURN,\n" 2367c478bd9Sstevel@tonic-gate "\tand that field will not appear in the output file.\n" 2377c478bd9Sstevel@tonic-gate "If you want to return to previous fields in the skeleton,\n" 2387c478bd9Sstevel@tonic-gate "\ta single minus sign will go back a field at a time.\n" 2397c478bd9Sstevel@tonic-gate "\t(This is the best way to input multiple authors.)\n" 2407c478bd9Sstevel@tonic-gate "If you have to continue a field or add an unusual field,\n" 2417c478bd9Sstevel@tonic-gate "\ta trailing backslash will allow a temporary escape.\n" 2427c478bd9Sstevel@tonic-gate "Finally, (without -a) you will be prompted for an abstract\n" 2437c478bd9Sstevel@tonic-gate "Type in as many lines as you need, and end with a ctrl-d.\n" 2447c478bd9Sstevel@tonic-gate "To quit, type `q' or `n' when asked if you want to continue.\n" 2457c478bd9Sstevel@tonic-gate "To edit the database, type `edit', `vi', or `ex' instead.")); 2467c478bd9Sstevel@tonic-gate 2477c478bd9Sstevel@tonic-gate } 2487c478bd9Sstevel@tonic-gate 249*11a8fa6cSceastha static void 250*11a8fa6cSceastha rd_skel(char *arg) /* redo bibskel from user-supplied file */ 2517c478bd9Sstevel@tonic-gate { 2527c478bd9Sstevel@tonic-gate FILE *pfp, *fopen(); 2537c478bd9Sstevel@tonic-gate char str[BUFSIZ]; 2547c478bd9Sstevel@tonic-gate int entry, i, j; 2557c478bd9Sstevel@tonic-gate 256*11a8fa6cSceastha if ((pfp = fopen(arg, "r")) == NULL) { 2577c478bd9Sstevel@tonic-gate fprintf(stderr, gettext("Promptfile ")); 2587c478bd9Sstevel@tonic-gate perror(arg); 2597c478bd9Sstevel@tonic-gate exit(1); 2607c478bd9Sstevel@tonic-gate } 261*11a8fa6cSceastha for (entry = 0; fgets(str, BUFSIZ, pfp); entry++) { 2627c478bd9Sstevel@tonic-gate for (i = 0; str[i] != '\t' && str[i] != '\n'; i++) 2637c478bd9Sstevel@tonic-gate bibskel[entry].prompt[i] = str[i]; 2647c478bd9Sstevel@tonic-gate bibskel[entry].prompt[i] = NULL; 265*11a8fa6cSceastha if (str[i] == '\n') { 266*11a8fa6cSceastha fprintf(stderr, gettext( 267*11a8fa6cSceastha "No tabs between promptfile fields.\n")); 268*11a8fa6cSceastha fprintf(stderr, gettext( 269*11a8fa6cSceastha "Format: prompt-string <TAB> %%key\n")); 2707c478bd9Sstevel@tonic-gate exit(1); 2717c478bd9Sstevel@tonic-gate } 2727c478bd9Sstevel@tonic-gate for (i++, j = 0; str[i] != '\n'; i++, j++) 2737c478bd9Sstevel@tonic-gate bibskel[entry].keylet[j] = str[i]; 2747c478bd9Sstevel@tonic-gate bibskel[entry].keylet[j] = NULL; 2757c478bd9Sstevel@tonic-gate 276*11a8fa6cSceastha if (entry >= MAXENT) { 277*11a8fa6cSceastha fprintf(stderr, gettext( 278*11a8fa6cSceastha "Too many entries in promptfile.\n")); 2797c478bd9Sstevel@tonic-gate exit(1); 2807c478bd9Sstevel@tonic-gate } 2817c478bd9Sstevel@tonic-gate } 2827c478bd9Sstevel@tonic-gate entries = entry; 2837c478bd9Sstevel@tonic-gate fclose(pfp); 2847c478bd9Sstevel@tonic-gate } 285