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*59915Sbostic static char sccsid[] = "@(#)w.c 5.8 (Berkeley) 05/11/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 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. */ 122*59915Sbostic if (Start == NULL) 123*59915Sbostic l_ttl = 0; 124*59915Sbostic else 125*59915Sbostic 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 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