157703Sbostic /*-
2*60663Sbostic * Copyright (c) 1992, 1993
3*60663Sbostic * The Regents of the University of California. All rights reserved.
457703Sbostic *
557703Sbostic * This code is derived from software contributed to Berkeley by
657703Sbostic * Rodney Ruddock of the University of Guelph.
757703Sbostic *
857703Sbostic * %sccs.include.redist.c%
957703Sbostic */
1057703Sbostic
1157703Sbostic #ifndef lint
12*60663Sbostic static char sccsid[] = "@(#)w.c 8.1 (Berkeley) 05/31/93";
1357703Sbostic #endif /* not lint */
1457703Sbostic
1557710Sbostic #include <sys/types.h>
1657710Sbostic
1759475Sbostic #include <limits.h>
1857710Sbostic #include <regex.h>
1957710Sbostic #include <setjmp.h>
2057710Sbostic #include <stdio.h>
2157710Sbostic #include <stdlib.h>
2257710Sbostic #include <string.h>
2357710Sbostic
2458315Sbostic #ifdef DBI
2558315Sbostic #include <db.h>
2658315Sbostic #endif
2758315Sbostic
2857703Sbostic #include "ed.h"
2957710Sbostic #include "extern.h"
3057703Sbostic
3157703Sbostic /*
3257703Sbostic * Write the contents of the buffer out to the real file (spec'd or
3357703Sbostic * remembered). If 'w' then overwrite, if 'W' append to the file. 'W'
3457703Sbostic * is probably _the_ command that most editors don't have, and it's
3557703Sbostic * so(!) useful. The 'wq' works as 'w' but 'q' immediately follows.
3657703Sbostic * Shame on POSIX for not including 'W' and 'wq', they're not that
3757703Sbostic * hard to implement; yaaa! BSD for keeping it! :-)
3857703Sbostic */
3957703Sbostic void
w(inputt,errnum)4057703Sbostic w(inputt, errnum)
4157710Sbostic FILE *inputt;
4257710Sbostic int *errnum;
4357703Sbostic {
4459475Sbostic FILE *l_fp;
4559475Sbostic int l_ttl = 0, l_q_flag = 0, l_sl, l_bang_flag=0;
4659475Sbostic char *filename_read=NULL, *l_temp;
4757703Sbostic
4858564Sralph if (Start_default && End_default) {
4958564Sralph Start = top;
5057710Sbostic End = bottom;
5157710Sbostic } else
5258564Sralph if (Start_default)
5358564Sralph Start = End;
5458564Sralph Start_default = End_default = 0;
5557703Sbostic
5657710Sbostic l_sl = ss;
5757710Sbostic ss = getc(inputt);
5857703Sbostic
5957710Sbostic if (ss == 'q') /* "wq" and "Wq" command */
6057710Sbostic l_q_flag = 1;
6157710Sbostic else
6257710Sbostic ungetc(ss, inputt);
6357703Sbostic
6459475Sbostic l_temp = filename(inputt, errnum);
6557710Sbostic if (*errnum == 1)
6659475Sbostic filename_read = l_temp;
6757710Sbostic else
6857710Sbostic if (*errnum == -2) {
6957710Sbostic while (((ss = getc(inputt)) != '\n') || (ss == EOF));
7057710Sbostic filename_read = filename_current;
7157710Sbostic } else
7257710Sbostic if (*errnum < 0)
7357710Sbostic return;
7457710Sbostic *errnum = 0;
7557703Sbostic
7657710Sbostic if (filename_current == NULL) {
7757710Sbostic if (filename_read == NULL) {
7857710Sbostic strcpy(help_msg, "no filename given");
7957710Sbostic *errnum = -1;
8057710Sbostic ungetc('\n', inputt);
8157710Sbostic return;
8257710Sbostic } else
8357710Sbostic filename_current = filename_read;
8457710Sbostic }
8558315Sbostic sigspecial++;
8659475Sbostic if (l_temp && l_temp[FILENAME_LEN+1]) { /* bang flag */
8759475Sbostic FILE *popen();
8859475Sbostic
8959475Sbostic if (l_temp[0] == '\0') {
9059475Sbostic strcpy(help_msg, "no command given");
9159475Sbostic *errnum = -1;
9259475Sbostic sigspecial--;
9359475Sbostic return;
9459475Sbostic }
9559475Sbostic if ((l_fp = popen(l_temp, "w")) == NULL) {
9659475Sbostic strcpy(help_msg, "error executing command");
9759475Sbostic *errnum = -1;
9859475Sbostic if (l_fp != NULL)
9959475Sbostic pclose(l_fp);
10059475Sbostic sigspecial--;
10159475Sbostic return;
10259475Sbostic }
10359475Sbostic l_bang_flag = 1;
10459475Sbostic }
10559475Sbostic else if (l_sl == 'W')
10659475Sbostic l_fp = fopen(filename_read, "a");
10757710Sbostic else
10859475Sbostic l_fp = fopen(filename_read, "w");
10957703Sbostic
11059475Sbostic if (l_fp == NULL) {
11157710Sbostic strcpy(help_msg, "cannot write to file");
11257710Sbostic *errnum = -1;
11357710Sbostic ungetc('\n', inputt);
11459475Sbostic sigspecial--;
11557710Sbostic return;
11657710Sbostic }
11758315Sbostic sigspecial--;
11858315Sbostic if (sigint_flag && (!sigspecial))
11957710Sbostic goto point;
12057703Sbostic
12157710Sbostic /* Write it out and get a report on the number of bytes written. */
12259915Sbostic if (Start == NULL)
12359915Sbostic l_ttl = 0;
12459915Sbostic else
12559915Sbostic l_ttl = edwrite(l_fp, Start, End);
12658710Sbostic if (explain_flag > 0) /* For -s option. */
12757710Sbostic printf("%d\n", l_ttl);
12857703Sbostic
12959475Sbostic point: if (l_bang_flag)
13059475Sbostic pclose(l_fp);
13159475Sbostic else
13259475Sbostic fclose(l_fp);
13357710Sbostic if (filename_read != filename_current)
13457710Sbostic free(filename_read);
13559558Sbostic if ((Start == top) && (End == bottom))
13659558Sbostic change_flag = 0L;
13757710Sbostic *errnum = 1;
13858315Sbostic if (l_q_flag) { /* For "wq" and "Wq". */
13957710Sbostic ungetc('\n', inputt);
14057710Sbostic ss = (int) 'q';
14157710Sbostic q(inputt, errnum);
14257710Sbostic }
14357703Sbostic }
14457703Sbostic
14557703Sbostic /*
14657703Sbostic * Actually writes out the contents of the buffer to the specified
14757703Sbostic * STDIO file pointer for the range of lines specified.
14857703Sbostic */
14957703Sbostic int
edwrite(fp,begi,fini)15057703Sbostic edwrite(fp, begi, fini)
15157710Sbostic FILE *fp;
15257710Sbostic LINE *begi, *fini;
15357710Sbostic {
15457710Sbostic register int l_ttl = 0;
15557703Sbostic
15657710Sbostic for (;;) {
15757710Sbostic get_line(begi->handle, begi->len);
15858315Sbostic if (sigint_flag && (!sigspecial))
15958315Sbostic break;
16057703Sbostic
16158315Sbostic sigspecial++;
16257710Sbostic /* Fwrite is about 20+% faster than fprintf -- no surprise. */
16357710Sbostic fwrite(text, sizeof(char), begi->len, fp);
16457710Sbostic fputc('\n', fp);
16557710Sbostic l_ttl = l_ttl + (begi->len) + 1;
16657710Sbostic if (begi == fini)
16757710Sbostic break;
16857710Sbostic else
16957710Sbostic begi = begi->below;
17058315Sbostic sigspecial--;
17158315Sbostic if (sigint_flag && (!sigspecial))
17258315Sbostic break;
17357710Sbostic }
17457710Sbostic return (l_ttl);
17557710Sbostic }
176