111a8fa6cSceastha /*
211a8fa6cSceastha * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
311a8fa6cSceastha * Use is subject to license terms.
411a8fa6cSceastha */
511a8fa6cSceastha
67c478bd9Sstevel@tonic-gate /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
7*7bc3049fSToomas Soome /* 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 #include <locale.h>
167c478bd9Sstevel@tonic-gate #include <stdio.h>
177c478bd9Sstevel@tonic-gate #include <ctype.h>
187c478bd9Sstevel@tonic-gate #include <signal.h>
1911a8fa6cSceastha #define MAXENT 50
207c478bd9Sstevel@tonic-gate
217c478bd9Sstevel@tonic-gate struct skeleton {
227c478bd9Sstevel@tonic-gate char prompt[20]; /* prompt user for entry */
23*7bc3049fSToomas Soome char keylet[5]; /* key letter for database */
247c478bd9Sstevel@tonic-gate } bibskel[MAXENT] = {
257c478bd9Sstevel@tonic-gate " Author:", "%A",
267c478bd9Sstevel@tonic-gate " Title:", "%T",
277c478bd9Sstevel@tonic-gate " Journal:", "%J",
28*7bc3049fSToomas Soome " Volume:", "%V",
297c478bd9Sstevel@tonic-gate " Pages:", "%P",
307c478bd9Sstevel@tonic-gate "Publisher:", "%I",
31*7bc3049fSToomas Soome " City:", "%C",
32*7bc3049fSToomas Soome " Date:", "%D",
337c478bd9Sstevel@tonic-gate " Other:", "%O",
347c478bd9Sstevel@tonic-gate " Keywords:", "%K", };
357c478bd9Sstevel@tonic-gate
367c478bd9Sstevel@tonic-gate int entries = 10; /* total number of entries in bibskel */
377c478bd9Sstevel@tonic-gate int abstract = 1; /* asking for abstracts is the default */
387c478bd9Sstevel@tonic-gate
3911a8fa6cSceastha static void addbib(FILE *, char *);
4011a8fa6cSceastha void bibedit(FILE *, char *, char *);
4111a8fa6cSceastha static void instruct(void);
4211a8fa6cSceastha static void rd_skel(char *);
4311a8fa6cSceastha static void trim(char []);
4411a8fa6cSceastha
4511a8fa6cSceastha static void
usage(void)4611a8fa6cSceastha usage(void) /* print proper usage and exit */
477c478bd9Sstevel@tonic-gate {
487c478bd9Sstevel@tonic-gate puts(gettext("Usage: addbib [-p promptfile] [-a] database\n\
497c478bd9Sstevel@tonic-gate \t-p: the promptfile defines alternate fields\n\
507c478bd9Sstevel@tonic-gate \t-a: don't include prompting for the abstract\n"));
517c478bd9Sstevel@tonic-gate exit(1);
527c478bd9Sstevel@tonic-gate }
537c478bd9Sstevel@tonic-gate
5411a8fa6cSceastha int
main(int argc,char * argv[])5511a8fa6cSceastha main(int argc, char *argv[]) /* addbib: bibliography entry program */
567c478bd9Sstevel@tonic-gate {
577c478bd9Sstevel@tonic-gate FILE *fp, *fopen();
587c478bd9Sstevel@tonic-gate int i;
597c478bd9Sstevel@tonic-gate
607c478bd9Sstevel@tonic-gate (void) setlocale(LC_ALL, "");
617c478bd9Sstevel@tonic-gate
627c478bd9Sstevel@tonic-gate #if !defined(TEXT_DOMAIN)
6311a8fa6cSceastha #define TEXT_DOMAIN "SYS_TEST"
647c478bd9Sstevel@tonic-gate #endif
657c478bd9Sstevel@tonic-gate (void) textdomain(TEXT_DOMAIN);
667c478bd9Sstevel@tonic-gate
6711a8fa6cSceastha if (argc == 1) {
6811a8fa6cSceastha puts(gettext(
6911a8fa6cSceastha "You must specify a bibliography file (database)."));
707c478bd9Sstevel@tonic-gate usage();
717c478bd9Sstevel@tonic-gate }
7211a8fa6cSceastha for (i = 1; argv[i][0] == '-'; i++) {
7311a8fa6cSceastha if (argv[i][1] == 'p') {
7411a8fa6cSceastha if (i >= argc - 2) {
7511a8fa6cSceastha puts(gettext("Not enough arguments for "
7611a8fa6cSceastha "-p option."));
777c478bd9Sstevel@tonic-gate usage();
787c478bd9Sstevel@tonic-gate }
797c478bd9Sstevel@tonic-gate rd_skel(argv[++i]);
8011a8fa6cSceastha } else if (argv[i][1] == 'a') {
8111a8fa6cSceastha if (i >= argc - 1) {
8211a8fa6cSceastha puts(gettext(
8311a8fa6cSceastha "No bibliofile specified after -a."));
847c478bd9Sstevel@tonic-gate usage();
857c478bd9Sstevel@tonic-gate }
867c478bd9Sstevel@tonic-gate abstract = 0;
8711a8fa6cSceastha } else { /* neither -p nor -a */
8811a8fa6cSceastha printf(gettext(
8911a8fa6cSceastha "Invalid command line flag: %s\n"), argv[i]);
907c478bd9Sstevel@tonic-gate usage();
917c478bd9Sstevel@tonic-gate }
927c478bd9Sstevel@tonic-gate }
9311a8fa6cSceastha if (i < argc - 1) {
947c478bd9Sstevel@tonic-gate puts(gettext("Too many arguments with no options."));
957c478bd9Sstevel@tonic-gate usage();
967c478bd9Sstevel@tonic-gate }
9711a8fa6cSceastha if ((fp = fopen(argv[i], "a")) == NULL) {
987c478bd9Sstevel@tonic-gate perror(argv[i]);
997c478bd9Sstevel@tonic-gate exit(1);
1007c478bd9Sstevel@tonic-gate }
1017c478bd9Sstevel@tonic-gate addbib(fp, argv[i]); /* loop for input */
10211a8fa6cSceastha return (0);
1037c478bd9Sstevel@tonic-gate }
1047c478bd9Sstevel@tonic-gate
10511a8fa6cSceastha static void
addbib(FILE * fp,char * argv)10611a8fa6cSceastha addbib(FILE *fp, char *argv) /* add entries to a bibliographic database */
1077c478bd9Sstevel@tonic-gate {
1087c478bd9Sstevel@tonic-gate char line[BUFSIZ];
1097c478bd9Sstevel@tonic-gate int i = 0, firstln, repeat = 0, escape = 0;
1107c478bd9Sstevel@tonic-gate
1117c478bd9Sstevel@tonic-gate printf(gettext("Instructions? "));
1127c478bd9Sstevel@tonic-gate fgets(line, BUFSIZ, stdin);
1137c478bd9Sstevel@tonic-gate if (line[0] == 'y' || line[0] == 'Y')
1147c478bd9Sstevel@tonic-gate instruct();
11511a8fa6cSceastha while (1) {
1167c478bd9Sstevel@tonic-gate putchar('\n');
1177c478bd9Sstevel@tonic-gate putc('\n', fp);
11811a8fa6cSceastha for (i = 0; i < entries; i++) {
1197c478bd9Sstevel@tonic-gate printf("%s\t", gettext(bibskel[i].prompt));
12011a8fa6cSceastha if (fgets(line, BUFSIZ, stdin) == NULL) {
1217c478bd9Sstevel@tonic-gate clearerr(stdin);
1227c478bd9Sstevel@tonic-gate break;
1237c478bd9Sstevel@tonic-gate }
12411a8fa6cSceastha if (line[0] == '-' && line[1] == '\n') {
1257c478bd9Sstevel@tonic-gate i -= 2;
12611a8fa6cSceastha if (i < -1) {
1277c478bd9Sstevel@tonic-gate printf(gettext("Too far back.\n"));
1287c478bd9Sstevel@tonic-gate i++;
1297c478bd9Sstevel@tonic-gate }
1307c478bd9Sstevel@tonic-gate continue;
13111a8fa6cSceastha } else if (line[strlen(line)-2] == '\\') {
13211a8fa6cSceastha if (line[0] != '\\') {
1337c478bd9Sstevel@tonic-gate line[strlen(line)-2] = '\n';
134*7bc3049fSToomas Soome line[strlen(line)-1] = '\0';
1357c478bd9Sstevel@tonic-gate trim(line);
1367c478bd9Sstevel@tonic-gate fprintf(fp, "%s %s",
13711a8fa6cSceastha bibskel[i].keylet, line);
1387c478bd9Sstevel@tonic-gate }
1397c478bd9Sstevel@tonic-gate printf("> ");
1407c478bd9Sstevel@tonic-gate again:
1417c478bd9Sstevel@tonic-gate fgets(line, BUFSIZ, stdin);
14211a8fa6cSceastha if (line[strlen(line)-2] == '\\') {
1437c478bd9Sstevel@tonic-gate line[strlen(line)-2] = '\n';
144*7bc3049fSToomas Soome line[strlen(line)-1] = '\0';
1457c478bd9Sstevel@tonic-gate trim(line);
1467c478bd9Sstevel@tonic-gate fputs(line, fp);
1477c478bd9Sstevel@tonic-gate printf("> ");
1487c478bd9Sstevel@tonic-gate goto again;
1497c478bd9Sstevel@tonic-gate }
1507c478bd9Sstevel@tonic-gate trim(line);
1517c478bd9Sstevel@tonic-gate fputs(line, fp);
15211a8fa6cSceastha } else if (line[0] != '\n') {
1537c478bd9Sstevel@tonic-gate trim(line);
1547c478bd9Sstevel@tonic-gate fprintf(fp, "%s %s", bibskel[i].keylet, line);
1557c478bd9Sstevel@tonic-gate }
1567c478bd9Sstevel@tonic-gate }
15711a8fa6cSceastha if (abstract) {
1587c478bd9Sstevel@tonic-gate puts(gettext(" Abstract: (ctrl-d to end)"));
1597c478bd9Sstevel@tonic-gate firstln = 1;
16011a8fa6cSceastha while (fgets(line, BUFSIZ, stdin)) {
16111a8fa6cSceastha if (firstln && line[0] != '%') {
1627c478bd9Sstevel@tonic-gate fprintf(fp, "%%X ");
1637c478bd9Sstevel@tonic-gate firstln = 0;
1647c478bd9Sstevel@tonic-gate }
1657c478bd9Sstevel@tonic-gate fputs(line, fp);
1667c478bd9Sstevel@tonic-gate }
1677c478bd9Sstevel@tonic-gate clearerr(stdin);
1687c478bd9Sstevel@tonic-gate }
1697c478bd9Sstevel@tonic-gate fflush(fp); /* write to file at end of each cycle */
17011a8fa6cSceastha if (ferror(fp)) {
1717c478bd9Sstevel@tonic-gate perror(argv);
1727c478bd9Sstevel@tonic-gate exit(1);
1737c478bd9Sstevel@tonic-gate }
1747c478bd9Sstevel@tonic-gate editloop:
1757c478bd9Sstevel@tonic-gate printf(gettext("\nContinue? "));
1767c478bd9Sstevel@tonic-gate fgets(line, BUFSIZ, stdin);
17711a8fa6cSceastha if (line[0] == 'e' || line[0] == 'v') {
1787c478bd9Sstevel@tonic-gate bibedit(fp, line, argv);
1797c478bd9Sstevel@tonic-gate goto editloop;
1807c478bd9Sstevel@tonic-gate }
1817c478bd9Sstevel@tonic-gate if (line[0] == 'q' || line[0] == 'n')
1827c478bd9Sstevel@tonic-gate return;
1837c478bd9Sstevel@tonic-gate }
1847c478bd9Sstevel@tonic-gate }
1857c478bd9Sstevel@tonic-gate
18611a8fa6cSceastha static void
trim(char line[])18711a8fa6cSceastha trim(char line[]) /* trim line of trailing white space */
1887c478bd9Sstevel@tonic-gate {
1897c478bd9Sstevel@tonic-gate int n;
1907c478bd9Sstevel@tonic-gate
1917c478bd9Sstevel@tonic-gate n = strlen(line);
19211a8fa6cSceastha while (--n >= 0) {
1937c478bd9Sstevel@tonic-gate if (!isspace(line[n]))
1947c478bd9Sstevel@tonic-gate break;
1957c478bd9Sstevel@tonic-gate }
1967c478bd9Sstevel@tonic-gate line[++n] = '\n';
197*7bc3049fSToomas Soome line[++n] = '\0';
1987c478bd9Sstevel@tonic-gate }
1997c478bd9Sstevel@tonic-gate
20011a8fa6cSceastha void
bibedit(FILE * fp,char * cmd,char * arg)20111a8fa6cSceastha bibedit(FILE *fp, char *cmd, char *arg) /* edit database with edit, ex, or vi */
2027c478bd9Sstevel@tonic-gate {
2037c478bd9Sstevel@tonic-gate int i = 0, status;
2047c478bd9Sstevel@tonic-gate
2057c478bd9Sstevel@tonic-gate fclose(fp);
2067c478bd9Sstevel@tonic-gate while (!isspace(cmd[i]))
2077c478bd9Sstevel@tonic-gate i++;
208*7bc3049fSToomas Soome cmd[i] = '\0';
20911a8fa6cSceastha if (fork() == 0) {
2107c478bd9Sstevel@tonic-gate if (cmd[0] == 'v' && cmd[1] == 'i')
2117c478bd9Sstevel@tonic-gate execlp(cmd, cmd, "+$", arg, NULL);
2127c478bd9Sstevel@tonic-gate else /* either ed, ex, or edit */
2137c478bd9Sstevel@tonic-gate execlp(cmd, cmd, arg, NULL);
2147c478bd9Sstevel@tonic-gate }
2157c478bd9Sstevel@tonic-gate signal(SIGINT, SIG_IGN);
2167c478bd9Sstevel@tonic-gate signal(SIGQUIT, SIG_IGN);
2177c478bd9Sstevel@tonic-gate wait(&status);
2187c478bd9Sstevel@tonic-gate signal(SIGINT, SIG_DFL);
2197c478bd9Sstevel@tonic-gate signal(SIGQUIT, SIG_DFL);
22011a8fa6cSceastha if ((fp = fopen(arg, "a")) == NULL) {
2217c478bd9Sstevel@tonic-gate perror(arg);
2227c478bd9Sstevel@tonic-gate exit(1);
2237c478bd9Sstevel@tonic-gate }
2247c478bd9Sstevel@tonic-gate }
2257c478bd9Sstevel@tonic-gate
22611a8fa6cSceastha static void
instruct(void)22711a8fa6cSceastha instruct(void) /* give user elementary directions */
2287c478bd9Sstevel@tonic-gate {
2297c478bd9Sstevel@tonic-gate putchar('\n');
23011a8fa6cSceastha puts(gettext(
23111a8fa6cSceastha "Addbib will prompt you for various bibliographic fields.\n"
2327c478bd9Sstevel@tonic-gate "If you don't need a particular field, just hit RETURN,\n"
2337c478bd9Sstevel@tonic-gate "\tand that field will not appear in the output file.\n"
2347c478bd9Sstevel@tonic-gate "If you want to return to previous fields in the skeleton,\n"
2357c478bd9Sstevel@tonic-gate "\ta single minus sign will go back a field at a time.\n"
2367c478bd9Sstevel@tonic-gate "\t(This is the best way to input multiple authors.)\n"
2377c478bd9Sstevel@tonic-gate "If you have to continue a field or add an unusual field,\n"
2387c478bd9Sstevel@tonic-gate "\ta trailing backslash will allow a temporary escape.\n"
2397c478bd9Sstevel@tonic-gate "Finally, (without -a) you will be prompted for an abstract\n"
2407c478bd9Sstevel@tonic-gate "Type in as many lines as you need, and end with a ctrl-d.\n"
2417c478bd9Sstevel@tonic-gate "To quit, type `q' or `n' when asked if you want to continue.\n"
2427c478bd9Sstevel@tonic-gate "To edit the database, type `edit', `vi', or `ex' instead."));
2437c478bd9Sstevel@tonic-gate
2447c478bd9Sstevel@tonic-gate }
2457c478bd9Sstevel@tonic-gate
24611a8fa6cSceastha static void
rd_skel(char * arg)24711a8fa6cSceastha rd_skel(char *arg) /* redo bibskel from user-supplied file */
2487c478bd9Sstevel@tonic-gate {
2497c478bd9Sstevel@tonic-gate FILE *pfp, *fopen();
2507c478bd9Sstevel@tonic-gate char str[BUFSIZ];
2517c478bd9Sstevel@tonic-gate int entry, i, j;
2527c478bd9Sstevel@tonic-gate
25311a8fa6cSceastha if ((pfp = fopen(arg, "r")) == NULL) {
2547c478bd9Sstevel@tonic-gate fprintf(stderr, gettext("Promptfile "));
2557c478bd9Sstevel@tonic-gate perror(arg);
2567c478bd9Sstevel@tonic-gate exit(1);
2577c478bd9Sstevel@tonic-gate }
25811a8fa6cSceastha for (entry = 0; fgets(str, BUFSIZ, pfp); entry++) {
2597c478bd9Sstevel@tonic-gate for (i = 0; str[i] != '\t' && str[i] != '\n'; i++)
2607c478bd9Sstevel@tonic-gate bibskel[entry].prompt[i] = str[i];
261*7bc3049fSToomas Soome bibskel[entry].prompt[i] = '\0';
26211a8fa6cSceastha if (str[i] == '\n') {
26311a8fa6cSceastha fprintf(stderr, gettext(
26411a8fa6cSceastha "No tabs between promptfile fields.\n"));
26511a8fa6cSceastha fprintf(stderr, gettext(
26611a8fa6cSceastha "Format: prompt-string <TAB> %%key\n"));
2677c478bd9Sstevel@tonic-gate exit(1);
2687c478bd9Sstevel@tonic-gate }
26911a8fa6cSceastha for (i++, j = 0; str[i] != '\n'; i++, j++)
2707c478bd9Sstevel@tonic-gate bibskel[entry].keylet[j] = str[i];
271*7bc3049fSToomas Soome bibskel[entry].keylet[j] = '\0';
2727c478bd9Sstevel@tonic-gate
27311a8fa6cSceastha if (entry >= MAXENT) {
27411a8fa6cSceastha fprintf(stderr, gettext(
27511a8fa6cSceastha "Too many entries in promptfile.\n"));
2767c478bd9Sstevel@tonic-gate exit(1);
2777c478bd9Sstevel@tonic-gate }
2787c478bd9Sstevel@tonic-gate }
2797c478bd9Sstevel@tonic-gate entries = entry;
2807c478bd9Sstevel@tonic-gate fclose(pfp);
2817c478bd9Sstevel@tonic-gate }
282