update from Rodney Ruddock (rodney@snowhite.cis.uoguelph.ca)
[unix-history] / usr / src / contrib / ed / w.c
CommitLineData
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 12static 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
39void
40w(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
129point: 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
149int
150edwrite(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}