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
usage(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
main(int argc,char * argv[])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
addbib(FILE * fp,char * argv)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
trim(char line[])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
bibedit(FILE * fp,char * cmd,char * arg)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
instruct(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
rd_skel(char * arg)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