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*59475Sbostic static char sccsid[] = "@(#)w.c 5.6 (Berkeley) 04/28/93"; 1357703Sbostic #endif /* not lint */ 1457703Sbostic 1557710Sbostic #include <sys/types.h> 1657710Sbostic 17*59475Sbostic #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 { 44*59475Sbostic FILE *l_fp; 45*59475Sbostic int l_ttl = 0, l_q_flag = 0, l_sl, l_bang_flag=0; 46*59475Sbostic 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 69*59475Sbostic l_temp = filename(inputt, errnum); 7057710Sbostic if (*errnum == 1) 71*59475Sbostic 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++; 91*59475Sbostic if (l_temp && l_temp[FILENAME_LEN+1]) { /* bang flag */ 92*59475Sbostic FILE *popen(); 93*59475Sbostic 94*59475Sbostic if (l_temp[0] == '\0') { 95*59475Sbostic strcpy(help_msg, "no command given"); 96*59475Sbostic *errnum = -1; 97*59475Sbostic sigspecial--; 98*59475Sbostic return; 99*59475Sbostic } 100*59475Sbostic if ((l_fp = popen(l_temp, "w")) == NULL) { 101*59475Sbostic strcpy(help_msg, "error executing command"); 102*59475Sbostic *errnum = -1; 103*59475Sbostic if (l_fp != NULL) 104*59475Sbostic pclose(l_fp); 105*59475Sbostic sigspecial--; 106*59475Sbostic return; 107*59475Sbostic } 108*59475Sbostic l_bang_flag = 1; 109*59475Sbostic } 110*59475Sbostic else if (l_sl == 'W') 111*59475Sbostic l_fp = fopen(filename_read, "a"); 11257710Sbostic else 113*59475Sbostic l_fp = fopen(filename_read, "w"); 11457703Sbostic 115*59475Sbostic if (l_fp == NULL) { 11657710Sbostic strcpy(help_msg, "cannot write to file"); 11757710Sbostic *errnum = -1; 11857710Sbostic ungetc('\n', inputt); 119*59475Sbostic 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. */ 127*59475Sbostic l_ttl = edwrite(l_fp, Start, End); 12858710Sbostic if (explain_flag > 0) /* For -s option. */ 12957710Sbostic printf("%d\n", l_ttl); 13057703Sbostic 131*59475Sbostic point: if (l_bang_flag) 132*59475Sbostic pclose(l_fp); 133*59475Sbostic else 134*59475Sbostic fclose(l_fp); 13557710Sbostic if (filename_read != filename_current) 13657710Sbostic free(filename_read); 13757710Sbostic change_flag = 0L; 13857710Sbostic *errnum = 1; 13958315Sbostic if (l_q_flag) { /* For "wq" and "Wq". */ 14057710Sbostic ungetc('\n', inputt); 14157710Sbostic ss = (int) 'q'; 14257710Sbostic q(inputt, errnum); 14357710Sbostic } 14457703Sbostic } 14557703Sbostic 14657703Sbostic /* 14757703Sbostic * Actually writes out the contents of the buffer to the specified 14857703Sbostic * STDIO file pointer for the range of lines specified. 14957703Sbostic */ 15057703Sbostic int 15157703Sbostic edwrite(fp, begi, fini) 15257710Sbostic FILE *fp; 15357710Sbostic LINE *begi, *fini; 15457710Sbostic { 15557710Sbostic register int l_ttl = 0; 15657703Sbostic 15757710Sbostic for (;;) { 15857710Sbostic get_line(begi->handle, begi->len); 15958315Sbostic if (sigint_flag && (!sigspecial)) 16058315Sbostic break; 16157703Sbostic 16258315Sbostic sigspecial++; 16357710Sbostic /* Fwrite is about 20+% faster than fprintf -- no surprise. */ 16457710Sbostic fwrite(text, sizeof(char), begi->len, fp); 16557710Sbostic fputc('\n', fp); 16657710Sbostic l_ttl = l_ttl + (begi->len) + 1; 16757710Sbostic if (begi == fini) 16857710Sbostic break; 16957710Sbostic else 17057710Sbostic begi = begi->below; 17158315Sbostic sigspecial--; 17258315Sbostic if (sigint_flag && (!sigspecial)) 17358315Sbostic break; 17457710Sbostic } 17557710Sbostic return (l_ttl); 17657710Sbostic } 177