Commit | Line | Data |
---|---|---|
801b1056 KB |
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 | |
05ee7127 | 12 | static char sccsid[] = "@(#)w.c 5.8 (Berkeley) %G%"; |
801b1056 KB |
13 | #endif /* not lint */ |
14 | ||
ecbf4ad0 KB |
15 | #include <sys/types.h> |
16 | ||
afdef93a | 17 | #include <limits.h> |
ecbf4ad0 KB |
18 | #include <regex.h> |
19 | #include <setjmp.h> | |
20 | #include <stdio.h> | |
21 | #include <stdlib.h> | |
22 | #include <string.h> | |
23 | ||
e692f66f KB |
24 | #ifdef DBI |
25 | #include <db.h> | |
26 | #endif | |
27 | ||
801b1056 | 28 | #include "ed.h" |
ecbf4ad0 | 29 | #include "extern.h" |
801b1056 KB |
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 | */ | |
801b1056 KB |
39 | void |
40 | w(inputt, errnum) | |
ecbf4ad0 KB |
41 | FILE *inputt; |
42 | int *errnum; | |
801b1056 | 43 | { |
afdef93a KB |
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; | |
ecbf4ad0 | 47 | |
035e94f8 RC |
48 | if (Start_default && End_default) { |
49 | Start = top; | |
ecbf4ad0 KB |
50 | End = bottom; |
51 | } else | |
035e94f8 RC |
52 | if (Start_default) |
53 | Start = End; | |
035e94f8 | 54 | Start_default = End_default = 0; |
ecbf4ad0 KB |
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 | ||
afdef93a | 64 | l_temp = filename(inputt, errnum); |
ecbf4ad0 | 65 | if (*errnum == 1) |
afdef93a | 66 | filename_read = l_temp; |
ecbf4ad0 KB |
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 | } | |
e692f66f | 85 | sigspecial++; |
afdef93a KB |
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"); | |
ecbf4ad0 | 107 | else |
afdef93a | 108 | l_fp = fopen(filename_read, "w"); |
ecbf4ad0 | 109 | |
afdef93a | 110 | if (l_fp == NULL) { |
ecbf4ad0 KB |
111 | strcpy(help_msg, "cannot write to file"); |
112 | *errnum = -1; | |
113 | ungetc('\n', inputt); | |
afdef93a | 114 | sigspecial--; |
ecbf4ad0 KB |
115 | return; |
116 | } | |
e692f66f KB |
117 | sigspecial--; |
118 | if (sigint_flag && (!sigspecial)) | |
ecbf4ad0 KB |
119 | goto point; |
120 | ||
121 | /* Write it out and get a report on the number of bytes written. */ | |
05ee7127 KB |
122 | if (Start == NULL) |
123 | l_ttl = 0; | |
124 | else | |
125 | l_ttl = edwrite(l_fp, Start, End); | |
672cc1c0 | 126 | if (explain_flag > 0) /* For -s option. */ |
ecbf4ad0 KB |
127 | printf("%d\n", l_ttl); |
128 | ||
afdef93a KB |
129 | point: if (l_bang_flag) |
130 | pclose(l_fp); | |
131 | else | |
132 | fclose(l_fp); | |
ecbf4ad0 KB |
133 | if (filename_read != filename_current) |
134 | free(filename_read); | |
71fc9f52 KB |
135 | if ((Start == top) && (End == bottom)) |
136 | change_flag = 0L; | |
ecbf4ad0 | 137 | *errnum = 1; |
e692f66f | 138 | if (l_q_flag) { /* For "wq" and "Wq". */ |
ecbf4ad0 KB |
139 | ungetc('\n', inputt); |
140 | ss = (int) 'q'; | |
141 | q(inputt, errnum); | |
142 | } | |
801b1056 KB |
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 | */ | |
801b1056 KB |
149 | int |
150 | edwrite(fp, begi, fini) | |
ecbf4ad0 KB |
151 | FILE *fp; |
152 | LINE *begi, *fini; | |
801b1056 | 153 | { |
ecbf4ad0 KB |
154 | register int l_ttl = 0; |
155 | ||
156 | for (;;) { | |
157 | get_line(begi->handle, begi->len); | |
e692f66f KB |
158 | if (sigint_flag && (!sigspecial)) |
159 | break; | |
ecbf4ad0 | 160 | |
e692f66f | 161 | sigspecial++; |
ecbf4ad0 KB |
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; | |
e692f66f KB |
170 | sigspecial--; |
171 | if (sigint_flag && (!sigspecial)) | |
172 | break; | |
ecbf4ad0 KB |
173 | } |
174 | return (l_ttl); | |
175 | } |