1 /*- 2 * Copyright (c) 1992 The Regents of the University of California. 3 * 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 5.6 (Berkeley) 04/28/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 if (Start == NULL) { 55 strcpy(help_msg, "buffer empty"); 56 *errnum = -1; 57 return; 58 } 59 Start_default = End_default = 0; 60 61 l_sl = ss; 62 ss = getc(inputt); 63 64 if (ss == 'q') /* "wq" and "Wq" command */ 65 l_q_flag = 1; 66 else 67 ungetc(ss, inputt); 68 69 l_temp = filename(inputt, errnum); 70 if (*errnum == 1) 71 filename_read = l_temp; 72 else 73 if (*errnum == -2) { 74 while (((ss = getc(inputt)) != '\n') || (ss == EOF)); 75 filename_read = filename_current; 76 } else 77 if (*errnum < 0) 78 return; 79 *errnum = 0; 80 81 if (filename_current == NULL) { 82 if (filename_read == NULL) { 83 strcpy(help_msg, "no filename given"); 84 *errnum = -1; 85 ungetc('\n', inputt); 86 return; 87 } else 88 filename_current = filename_read; 89 } 90 sigspecial++; 91 if (l_temp && l_temp[FILENAME_LEN+1]) { /* bang flag */ 92 FILE *popen(); 93 94 if (l_temp[0] == '\0') { 95 strcpy(help_msg, "no command given"); 96 *errnum = -1; 97 sigspecial--; 98 return; 99 } 100 if ((l_fp = popen(l_temp, "w")) == NULL) { 101 strcpy(help_msg, "error executing command"); 102 *errnum = -1; 103 if (l_fp != NULL) 104 pclose(l_fp); 105 sigspecial--; 106 return; 107 } 108 l_bang_flag = 1; 109 } 110 else if (l_sl == 'W') 111 l_fp = fopen(filename_read, "a"); 112 else 113 l_fp = fopen(filename_read, "w"); 114 115 if (l_fp == NULL) { 116 strcpy(help_msg, "cannot write to file"); 117 *errnum = -1; 118 ungetc('\n', inputt); 119 sigspecial--; 120 return; 121 } 122 sigspecial--; 123 if (sigint_flag && (!sigspecial)) 124 goto point; 125 126 /* Write it out and get a report on the number of bytes written. */ 127 l_ttl = edwrite(l_fp, Start, End); 128 if (explain_flag > 0) /* For -s option. */ 129 printf("%d\n", l_ttl); 130 131 point: if (l_bang_flag) 132 pclose(l_fp); 133 else 134 fclose(l_fp); 135 if (filename_read != filename_current) 136 free(filename_read); 137 change_flag = 0L; 138 *errnum = 1; 139 if (l_q_flag) { /* For "wq" and "Wq". */ 140 ungetc('\n', inputt); 141 ss = (int) 'q'; 142 q(inputt, errnum); 143 } 144 } 145 146 /* 147 * Actually writes out the contents of the buffer to the specified 148 * STDIO file pointer for the range of lines specified. 149 */ 150 int 151 edwrite(fp, begi, fini) 152 FILE *fp; 153 LINE *begi, *fini; 154 { 155 register int l_ttl = 0; 156 157 for (;;) { 158 get_line(begi->handle, begi->len); 159 if (sigint_flag && (!sigspecial)) 160 break; 161 162 sigspecial++; 163 /* Fwrite is about 20+% faster than fprintf -- no surprise. */ 164 fwrite(text, sizeof(char), begi->len, fp); 165 fputc('\n', fp); 166 l_ttl = l_ttl + (begi->len) + 1; 167 if (begi == fini) 168 break; 169 else 170 begi = begi->below; 171 sigspecial--; 172 if (sigint_flag && (!sigspecial)) 173 break; 174 } 175 return (l_ttl); 176 } 177