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
w(inputt,errnum)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
edwrite(fp,begi,fini)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