/* * * Copyright (C) 1989 by the Massachusetts Institute of Technology * Developed by the MIT Student Information Processing Board (SIPB). * For copying information, see the file mit-copyright.h in this release. * */ /* * $Id: edit.c,v 1.16 1999-02-02 20:39:46 kcr Exp $ * * Utility routines. * * */ #ifndef lint static char rcsid_discuss_utils_c[] = "$Id: edit.c,v 1.16 1999-02-02 20:39:46 kcr Exp $"; #endif /* lint */ #include #include #include #include #include #include #include "globals.h" #include #if HAVE_SYS_WAIT_H #include #endif #ifndef WEXITSTATUS #define WEXITSTATUS(stat_val) ((unsigned)(stat_val) >> 8) #endif #include #include bool use_editor = TRUE; char *editor_path = NULL; extern char *getenv(); /* * int edit(fn, editor) * * fn: pathname of file to edit * * editor: * name of editor command to run; if NULL, use the default * (specified on the command line or $EDITOR); if "", use a simple * type-in prompter. * * return value: error_code if error occurs, or child exits with nonzero * status, 0 otherwise * * call up an editor (from environment variable EDITOR or default * value DEFAULT_EDITOR) on the specified file. */ int edit(fn, edit_path) char *fn; char *edit_path; { char *editor_path_e, *editor_path_2 = NULL; char *editor_path_v; int pid; int (*handler)(); int wbuf; struct stat buf; char buffer[BUFSIZ]; FILE *the_file = NULL; #if HAVE_SIGACTION struct sigaction act, oact; sigemptyset(&act.sa_mask); act.sa_flags = 0; #endif editor_path_e = getenv("EDITOR"); if (!editor_path_e) editor_path_e = "/bin/ed"; editor_path_v = getenv("VISUAL"); if (!editor_path_v) editor_path_v = "/usr/ucb/vi"; if (use_editor && editor_path && !edit_path) editor_path_2 = editor_path; else if (edit_path && (*edit_path != '\0')) editor_path_2 = edit_path; else { the_file = fopen(fn, "w"); if (!the_file) { perror(fn); printf("Error opening file: %d\n",errno); return(errno); } ftruncate(fileno(the_file), 0); fchmod(fileno(the_file), 0700); printf("Enter transaction; end with ^D or '.' on a line by itself.\n"); for (;;) { if ((gets(buffer) == NULL) || interrupt || !strcmp(buffer, ".")) break; else if (!strcmp(buffer,"\\f")) { editor_path_2 = editor_path_e; break; } else if (!strcmp(buffer,"~e")) { editor_path_2 = editor_path_e; break; } else if (!strcmp(buffer,"~v")) { editor_path_2 = editor_path_v; break; } else { fputs(buffer,the_file); fputc('\n',the_file); } } } if (editor_path_2) { if (the_file) { clearerr(stdin); fclose(the_file); } switch ((pid = fork())) { case -1: perror("couldn't fork"); printf("Couldn't fork, error %d\n",errno); return(errno); case 0: (void) execlp(editor_path_2, editor_path_2, fn, 0); (void) perror(editor_path_2); exit(1); default: break; } #if HAVE_SIGACTION act.sa_handler= (void (*)()) SIG_IGN; (void) sigaction(SIGINT, &act, &oact); #else handler = signal(SIGINT, SIG_IGN); #endif while (wait(&wbuf) != pid) ; #if HAVE_SIGACTION (void) sigaction(SIGINT, &oact, NULL); #else (void) signal(SIGINT, handler); #endif if (WIFSIGNALED(wbuf)) return(ET_CHILD_DIED); if (WEXITSTATUS(wbuf)) return(ET_CHILD_ERR); } else { clearerr(stdin); fclose(the_file); } if (stat (fn, &buf) != 0 || buf.st_size == 0) { unlink(fn); } return(0); } touch(fn) char *fn; { int fd; if ((fd=creat(fn, 0600)) < 0) return(errno); else close(fd); return(0); }