157703Sbostic /*- 257703Sbostic * Copyright (c) 1992 The Regents of the University of California. 357703Sbostic * 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*59558Sbostic static char sccsid[] = "@(#)w.c 5.7 (Berkeley) 04/30/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 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 if (Start == NULL) { 5558315Sbostic strcpy(help_msg, "buffer empty"); 5657710Sbostic *errnum = -1; 5757710Sbostic return; 5857710Sbostic } 5958564Sralph Start_default = End_default = 0; 6057703Sbostic 6157710Sbostic l_sl = ss; 6257710Sbostic ss = getc(inputt); 6357703Sbostic 6457710Sbostic if (ss == 'q') /* "wq" and "Wq" command */ 6557710Sbostic l_q_flag = 1; 6657710Sbostic else 6757710Sbostic ungetc(ss, inputt); 6857703Sbostic 6959475Sbostic l_temp = filename(inputt, errnum); 7057710Sbostic if (*errnum == 1) 7159475Sbostic filename_read = l_temp; 7257710Sbostic else 7357710Sbostic if (*errnum == -2) { 7457710Sbostic while (((ss = getc(inputt)) != '\n') || (ss == EOF)); 7557710Sbostic filename_read = filename_current; 7657710Sbostic } else 7757710Sbostic if (*errnum < 0) 7857710Sbostic return; 7957710Sbostic *errnum = 0; 8057703Sbostic 8157710Sbostic if (filename_current == NULL) { 8257710Sbostic if (filename_read == NULL) { 8357710Sbostic strcpy(help_msg, "no filename given"); 8457710Sbostic *errnum = -1; 8557710Sbostic ungetc('\n', inputt); 8657710Sbostic return; 8757710Sbostic } else 8857710Sbostic filename_current = filename_read; 8957710Sbostic } 9058315Sbostic sigspecial++; 9159475Sbostic if (l_temp && l_temp[FILENAME_LEN+1]) { /* bang flag */ 9259475Sbostic FILE *popen(); 9359475Sbostic 9459475Sbostic if (l_temp[0] == '\0') { 9559475Sbostic strcpy(help_msg, "no command given"); 9659475Sbostic *errnum = -1; 9759475Sbostic sigspecial--; 9859475Sbostic return; 9959475Sbostic } 10059475Sbostic if ((l_fp = popen(l_temp, "w")) == NULL) { 10159475Sbostic strcpy(help_msg, "error executing command"); 10259475Sbostic *errnum = -1; 10359475Sbostic if (l_fp != NULL) 10459475Sbostic pclose(l_fp); 10559475Sbostic sigspecial--; 10659475Sbostic return; 10759475Sbostic } 10859475Sbostic l_bang_flag = 1; 10959475Sbostic } 11059475Sbostic else if (l_sl == 'W') 11159475Sbostic l_fp = fopen(filename_read, "a"); 11257710Sbostic else 11359475Sbostic l_fp = fopen(filename_read, "w"); 11457703Sbostic 11559475Sbostic if (l_fp == NULL) { 11657710Sbostic strcpy(help_msg, "cannot write to file"); 11757710Sbostic *errnum = -1; 11857710Sbostic ungetc('\n', inputt); 11959475Sbostic sigspecial--; 12057710Sbostic return; 12157710Sbostic } 12258315Sbostic sigspecial--; 12358315Sbostic if (sigint_flag && (!sigspecial)) 12457710Sbostic goto point; 12557703Sbostic 12657710Sbostic /* Write it out and get a report on the number of bytes written. */ 12759475Sbostic l_ttl = edwrite(l_fp, Start, End); 12858710Sbostic if (explain_flag > 0) /* For -s option. */ 12957710Sbostic printf("%d\n", l_ttl); 13057703Sbostic 13159475Sbostic point: if (l_bang_flag) 13259475Sbostic pclose(l_fp); 13359475Sbostic else 13459475Sbostic fclose(l_fp); 13557710Sbostic if (filename_read != filename_current) 13657710Sbostic free(filename_read); 137*59558Sbostic if ((Start == top) && (End == bottom)) 138*59558Sbostic change_flag = 0L; 13957710Sbostic *errnum = 1; 14058315Sbostic if (l_q_flag) { /* For "wq" and "Wq". */ 14157710Sbostic ungetc('\n', inputt); 14257710Sbostic ss = (int) 'q'; 14357710Sbostic q(inputt, errnum); 14457710Sbostic } 14557703Sbostic } 14657703Sbostic 14757703Sbostic /* 14857703Sbostic * Actually writes out the contents of the buffer to the specified 14957703Sbostic * STDIO file pointer for the range of lines specified. 15057703Sbostic */ 15157703Sbostic int 15257703Sbostic edwrite(fp, begi, fini) 15357710Sbostic FILE *fp; 15457710Sbostic LINE *begi, *fini; 15557710Sbostic { 15657710Sbostic register int l_ttl = 0; 15757703Sbostic 15857710Sbostic for (;;) { 15957710Sbostic get_line(begi->handle, begi->len); 16058315Sbostic if (sigint_flag && (!sigspecial)) 16158315Sbostic break; 16257703Sbostic 16358315Sbostic sigspecial++; 16457710Sbostic /* Fwrite is about 20+% faster than fprintf -- no surprise. */ 16557710Sbostic fwrite(text, sizeof(char), begi->len, fp); 16657710Sbostic fputc('\n', fp); 16757710Sbostic l_ttl = l_ttl + (begi->len) + 1; 16857710Sbostic if (begi == fini) 16957710Sbostic break; 17057710Sbostic else 17157710Sbostic begi = begi->below; 17258315Sbostic sigspecial--; 17358315Sbostic if (sigint_flag && (!sigspecial)) 17458315Sbostic break; 17557710Sbostic } 17657710Sbostic return (l_ttl); 17757710Sbostic } 178