1 /*- 2 * Copyright (c) 1992, 1993 3 * The Regents of the University of California. All rights reserved. 4 * 5 * This code is derived from software contributed to Berkeley by 6 * Rodney Ruddock of the University of Guelph. 7 * 8 * %sccs.include.redist.c% 9 */ 10 11 #ifndef lint 12 static char sccsid[] = "@(#)w.c 8.1 (Berkeley) 05/31/93"; 13 #endif /* not lint */ 14 15 #include <sys/types.h> 16 17 #include <limits.h> 18 #include <regex.h> 19 #include <setjmp.h> 20 #include <stdio.h> 21 #include <stdlib.h> 22 #include <string.h> 23 24 #ifdef DBI 25 #include <db.h> 26 #endif 27 28 #include "ed.h" 29 #include "extern.h" 30 31 /* 32 * Write the contents of the buffer out to the real file (spec'd or 33 * remembered). If 'w' then overwrite, if 'W' append to the file. 'W' 34 * is probably _the_ command that most editors don't have, and it's 35 * so(!) useful. The 'wq' works as 'w' but 'q' immediately follows. 36 * Shame on POSIX for not including 'W' and 'wq', they're not that 37 * hard to implement; yaaa! BSD for keeping it! :-) 38 */ 39 void 40 w(inputt, errnum) 41 FILE *inputt; 42 int *errnum; 43 { 44 FILE *l_fp; 45 int l_ttl = 0, l_q_flag = 0, l_sl, l_bang_flag=0; 46 char *filename_read=NULL, *l_temp; 47 48 if (Start_default && End_default) { 49 Start = top; 50 End = bottom; 51 } else 52 if (Start_default) 53 Start = End; 54 Start_default = End_default = 0; 55 56 l_sl = ss; 57 ss = getc(inputt); 58 59 if (ss == 'q') /* "wq" and "Wq" command */ 60 l_q_flag = 1; 61 else 62 ungetc(ss, inputt); 63 64 l_temp = filename(inputt, errnum); 65 if (*errnum == 1) 66 filename_read = l_temp; 67 else 68 if (*errnum == -2) { 69 while (((ss = getc(inputt)) != '\n') || (ss == EOF)); 70 filename_read = filename_current; 71 } else 72 if (*errnum < 0) 73 return; 74 *errnum = 0; 75 76 if (filename_current == NULL) { 77 if (filename_read == NULL) { 78 strcpy(help_msg, "no filename given"); 79 *errnum = -1; 80 ungetc('\n', inputt); 81 return; 82 } else 83 filename_current = filename_read; 84 } 85 sigspecial++; 86 if (l_temp && l_temp[FILENAME_LEN+1]) { /* bang flag */ 87 FILE *popen(); 88 89 if (l_temp[0] == '\0') { 90 strcpy(help_msg, "no command given"); 91 *errnum = -1; 92 sigspecial--; 93 return; 94 } 95 if ((l_fp = popen(l_temp, "w")) == NULL) { 96 strcpy(help_msg, "error executing command"); 97 *errnum = -1; 98 if (l_fp != NULL) 99 pclose(l_fp); 100 sigspecial--; 101 return; 102 } 103 l_bang_flag = 1; 104 } 105 else if (l_sl == 'W') 106 l_fp = fopen(filename_read, "a"); 107 else 108 l_fp = fopen(filename_read, "w"); 109 110 if (l_fp == NULL) { 111 strcpy(help_msg, "cannot write to file"); 112 *errnum = -1; 113 ungetc('\n', inputt); 114 sigspecial--; 115 return; 116 } 117 sigspecial--; 118 if (sigint_flag && (!sigspecial)) 119 goto point; 120 121 /* Write it out and get a report on the number of bytes written. */ 122 if (Start == NULL) 123 l_ttl = 0; 124 else 125 l_ttl = edwrite(l_fp, Start, End); 126 if (explain_flag > 0) /* For -s option. */ 127 printf("%d\n", l_ttl); 128 129 point: if (l_bang_flag) 130 pclose(l_fp); 131 else 132 fclose(l_fp); 133 if (filename_read != filename_current) 134 free(filename_read); 135 if ((Start == top) && (End == bottom)) 136 change_flag = 0L; 137 *errnum = 1; 138 if (l_q_flag) { /* For "wq" and "Wq". */ 139 ungetc('\n', inputt); 140 ss = (int) 'q'; 141 q(inputt, errnum); 142 } 143 } 144 145 /* 146 * Actually writes out the contents of the buffer to the specified 147 * STDIO file pointer for the range of lines specified. 148 */ 149 int 150 edwrite(fp, begi, fini) 151 FILE *fp; 152 LINE *begi, *fini; 153 { 154 register int l_ttl = 0; 155 156 for (;;) { 157 get_line(begi->handle, begi->len); 158 if (sigint_flag && (!sigspecial)) 159 break; 160 161 sigspecial++; 162 /* Fwrite is about 20+% faster than fprintf -- no surprise. */ 163 fwrite(text, sizeof(char), begi->len, fp); 164 fputc('\n', fp); 165 l_ttl = l_ttl + (begi->len) + 1; 166 if (begi == fini) 167 break; 168 else 169 begi = begi->below; 170 sigspecial--; 171 if (sigint_flag && (!sigspecial)) 172 break; 173 } 174 return (l_ttl); 175 } 176