00001
00002
00003
00004
00005
00006
00007
00008
00009
00010 #include "elle.h"
00011 #include <stdio.h>
00012 #ifndef BUFSIZ
00013 #define BUFSIZ BUFSIZE
00014 #endif
00015 #if V6
00016 struct stat {
00017 int st_dev;
00018 int st_ino;
00019 char *st_mode;
00020 char st_nlink;
00021 char st_uid;
00022 char st_gid;
00023 char st_size0;
00024 char st_size;
00025 int st_addr[8];
00026 long st_atime;
00027 long st_mtime;
00028 };
00029 #define ENOENT (2)
00030 #else
00031 #include <errno.h>
00032 #include <sys/types.h>
00033 #include <sys/stat.h>
00034 #endif
00035
00036 #if TOPS20
00037 #include <sys/file.h>
00038 #endif
00039
00040 extern char *strerror();
00041 extern struct buffer *make_buf(), *find_buf();
00042
00043 char *fncons(), *last_fname();
00044
00045 int hoardfd = -1;
00046
00047
00048 #define WF_SMASK 07
00049 #define WF_SBUFF 0
00050 #define WF_SREG 1
00051 #define WF_SKILL 2
00052 #define WF_ASK 010
00053 static int iwritfile();
00054
00055
00056
00057
00058
00059
00060 f_ffile()
00061 { int find_file();
00062 #if IMAGEN
00063 hack_file("Visit file: ", find_file);
00064 #else
00065 hack_file("Find file: ", find_file);
00066 #endif
00067 }
00068
00069
00070
00071
00072 f_rfile() { u_r_file("Read file: "); }
00073
00074
00075
00076
00077 f_vfile() { u_r_file("Visit file: "); }
00078
00079
00080 u_r_file(prompt)
00081 char *prompt;
00082 { register char *f_name;
00083 register struct buffer *b;
00084
00085 if((f_name = ask (prompt))==0)
00086 return;
00087 b = cur_buf;
00088 if(*f_name == '\0')
00089 { if (b -> b_fn == 0)
00090 ding("No default file name.");
00091 else read_file(b -> b_fn);
00092 }
00093 else read_file(f_name);
00094 chkfree(f_name);
00095 }
00096
00097
00098
00099
00100
00101 f_ifile()
00102 { int ins_file();
00103 hack_file("Insert file: ", ins_file);
00104 }
00105
00106
00107
00108
00109 f_sfile()
00110 { if(cur_buf->b_flags&B_MODIFIED)
00111 return(iwritfile(WF_SBUFF));
00112 else
00113 { saynow("(No changes need to be written)");
00114 return(1);
00115 }
00116 }
00117
00118 #if FX_SAVEFILES || FX_WFEXIT
00119
00120
00121
00122
00123
00124 f_savefiles()
00125 { register struct buffer *b, *savb;
00126 register int res = 1;
00127 char *ans;
00128
00129 savb = cur_buf;
00130 for (b = buf_head; res && b; b = b->b_next)
00131 if ((b->b_flags & B_MODIFIED) && b->b_fn)
00132 { if(exp_p)
00133 { chg_buf(b);
00134 res = f_sfile();
00135 continue;
00136 }
00137
00138 ans = ask("Buffer %s contains changes - write out? ",
00139 b->b_name);
00140 if(ans == 0)
00141 { res = 0;
00142 break;
00143 }
00144 if (upcase(*ans) == 'Y')
00145 { chg_buf(b);
00146 res = f_sfile();
00147 }
00148 chkfree(ans);
00149 }
00150 chg_buf(savb);
00151 return(res);
00152 }
00153 #endif
00154
00155
00156
00157
00158 f_wfile()
00159 { return iwritfile(WF_ASK|WF_SBUFF);
00160 }
00161
00162
00163
00164
00165 f_wreg()
00166 { return iwritfile(WF_ASK|WF_SREG);
00167 }
00168
00169 #if FX_WLASTKILL
00170
00171
00172
00173
00174 extern int kill_ptr;
00175 extern SBSTR *kill_ring[];
00176
00177 f_wlastkill()
00178 { return iwritfile(WF_ASK|WF_SKILL);
00179 }
00180 #endif
00181
00182
00183
00184
00185 hack_file(prompt, rtn)
00186 char *prompt;
00187 int (*rtn)();
00188 { register char *f_name;
00189
00190 if((f_name = ask(prompt)) == 0)
00191 return;
00192 if (*f_name != '\0')
00193 (*rtn)(f_name);
00194 chkfree(f_name);
00195 }
00196
00197
00198
00199
00200
00201
00202 find_file(f_name)
00203 register char *f_name;
00204 { register struct buffer *b;
00205 register char *ans;
00206 char *lastn;
00207 int fd;
00208
00209 #if IMAGEN
00210 char real_name[128];
00211 expand_file(real_name, f_name);
00212 f_name = real_name;
00213 #endif
00214
00215 for (b = buf_head; b; b = b -> b_next)
00216 if(b->b_fn && (strcmp (b -> b_fn, f_name) == 0))
00217 break;
00218 if (b)
00219 { sel_buf(b);
00220 return;
00221 }
00222 if((fd = open(f_name,0)) < 0)
00223 { if(errno != ENOENT)
00224 { ferr_ropn();
00225 return;
00226 }
00227 }
00228 else close(fd);
00229
00230
00231 lastn = last_fname(f_name);
00232 b = find_buf(lastn);
00233 if (b && (ex_blen(b) || b->b_fn))
00234 { ans = ask("Buffer %s contains %s, which buffer shall I use? ",
00235 b -> b_name, b->b_fn ? b->b_fn : "something");
00236 if(ans == 0) return;
00237 if (*ans != '\0')
00238 b = make_buf(ans);
00239 chkfree(ans);
00240 }
00241 else
00242 b = make_buf(lastn);
00243 sel_buf(b);
00244 if(fd < 0)
00245 { set_fn(f_name);
00246 return;
00247 }
00248 if (read_file(f_name)==0)
00249 { if(b->b_fn)
00250 { chkfree(b->b_fn);
00251 b->b_fn = 0;
00252 }
00253 }
00254 }
00255
00256
00257
00258
00259
00260
00261 read_file(f_name)
00262 char *f_name;
00263 {
00264 #if IMAGEN
00265 struct stat s;
00266 char real_name[128];
00267 #endif
00268
00269 if(!zap_buffer())
00270 return;
00271 #if IMAGEN
00272 expand_file(real_name, f_name);
00273 f_name = real_name;
00274 #endif
00275 set_fn(f_name);
00276 if (ins_file(f_name)==0)
00277 return 0;
00278 f_bufnotmod();
00279 #if IMAGEN
00280 stat(f_name, &s);
00281 cur_buf->b_mtime = s.st_mtime;
00282 #endif
00283 return 1;
00284 }
00285
00286
00287
00288
00289
00290
00291 ins_file (f_name)
00292 char *f_name;
00293 { register int ifd;
00294 register SBSTR *sd;
00295 chroff insdot;
00296
00297 #if IMAGEN
00298 char real_name[128];
00299 expand_file(real_name, f_name);
00300 f_name = real_name;
00301 #endif
00302 #if !(TOPS20)
00303 if((ifd = open(f_name,0)) < 0)
00304 #else
00305 if((ifd = open(f_name,O_RDONLY|O_UNCONVERTED)) < 0)
00306 #endif
00307 { ferr_ropn();
00308 return 0;
00309 }
00310 errno = 0;
00311 if((sd = sb_fduse(ifd)) == 0)
00312 { if (ifd >= SB_NFILES)
00313 dingtoo(" Cannot read - too many internal files");
00314 else if (errno)
00315 ferr_ropn();
00316 else errbarf("SB rtn cannot read file?");
00317 close(ifd);
00318 return 0;
00319 }
00320 sb_sins(cur_buf,sd);
00321 insdot = e_dot();
00322 f_setmark();
00323 if(cur_dot != insdot)
00324 buf_tmat(insdot);
00325 e_gocur();
00326 return 1;
00327 }
00328
00329 ferr_ropn() { ferr(" Cannot read"); }
00330 ferr_wopn() { ferr(" Cannot write"); }
00331 ferr(str)
00332 char *str;
00333 { saytoo(str);
00334 saytoo(" - ");
00335 dingtoo(strerror(errno));
00336 }
00337
00338
00339
00340
00341
00342 static int
00343 iwritfile(flags)
00344 int flags;
00345 { register struct buffer *b;
00346 register char *o_name;
00347 int styp = flags & WF_SMASK;
00348 char *prompt;
00349 #ifdef STDWRITE
00350 register FILE *o_file;
00351 char obuf[BUFSIZ];
00352 chroff dotcnt;
00353 #endif
00354 int ofd;
00355 SBSTR *sd;
00356 char fname[FNAMSIZ];
00357 char newname[FNAMSIZ];
00358 char oldname[FNAMSIZ];
00359 int res;
00360 struct stat statb;
00361 int statres;
00362 #if IMAGEN
00363 struct stat s;
00364 char real_name[128];
00365 #endif
00366 res = 1;
00367
00368
00369 switch(styp)
00370 {
00371 case WF_SBUFF:
00372 prompt = "Write File: ";
00373 break;
00374 case WF_SREG:
00375 if(!mark_p)
00376 { dingtoo(" No Mark!");
00377 return(0);
00378 }
00379 prompt = "Write Region: ";
00380 break;
00381 #if FX_WLASTKILL
00382 case WF_SKILL:
00383 if(!kill_ring[kill_ptr])
00384 { dingtoo("No killed stuff");
00385 return(0);
00386 }
00387 prompt = "Write Last Kill: ";
00388 break;
00389 #endif
00390 default:
00391 errbarf("bad iwritfile arg");
00392 return 0;
00393 }
00394
00395 if (flags&WF_ASK)
00396 { if((o_name = ask(prompt))==0)
00397 return(0);
00398 strcpy(&fname[0], o_name);
00399 chkfree(o_name);
00400 }
00401 o_name = &fname[0];
00402 b = cur_buf;
00403 if (!(flags&WF_ASK) || (*o_name == '\0'))
00404 { if (b->b_fn == 0)
00405 { ding("No default file name.");
00406 return(0);
00407 }
00408 strcpy(o_name, b->b_fn);
00409 }
00410
00411 #if IMAGEN
00412 expand_file(real_name, o_name);
00413 o_name = real_name;
00414 #endif
00415
00416 statres = stat(o_name,&statb);
00417
00418 #if IMAGEN
00419
00420 if ((styp==WF_SBUFF) && !(flags&WF_ASK)
00421 && b->b_fn && stat(b->b_fn, &s) >= 0)
00422 if (s.st_mtime != b->b_mtime)
00423 { char *ans;
00424 ans = ask("Since you last read \"%s\", someone has changed it.\nDo you want to write it anyway (NOT RECOMMENDED!)? ",
00425 b->b_fn);
00426 if (ans == 0 || upcase(*ans) != 'Y')
00427 {
00428 ding("I suggest you either read it again, or\nwrite it to a temporary file, and merge the two versions manually.");
00429 if (ans) chkfree(ans);
00430 return(0);
00431 }
00432 if (ans) chkfree(ans);
00433 }
00434 #endif
00435
00436
00437
00438
00439
00440
00441
00442 fncons(oldname,ev_fno1,o_name,ev_fno2);
00443 fncons(newname,ev_fnn1,o_name,ev_fnn2);
00444 unlink(newname);
00445 unhoard();
00446 #if !(V6)
00447 if(statres >= 0)
00448 { if(access(o_name, 2) != 0)
00449 { ferr_wopn();
00450 res = 0;
00451 goto wdone;
00452 }
00453 }
00454 #endif
00455 #ifdef STDWRITE
00456 if(flags&WF_ASK)
00457 { if((o_file = fopen(newname, "w")) ==0)
00458 { ferr_wopn();
00459 res = 0;
00460 goto wdone;
00461 }
00462 setbuf(o_file,obuf);
00463 }
00464 else
00465 #endif
00466 {
00467 #if !(TOPS20)
00468 if((ofd = creat(newname,ev_filmod)) < 0)
00469 #else
00470 if((ofd = open(newname,O_WRONLY|O_UNCONVERTED)) < 0)
00471 #endif
00472 { ferr_wopn();
00473 res = 0;
00474 goto wdone;
00475 }
00476 }
00477 if (styp==WF_SBUFF)
00478 set_fn(o_name);
00479 #if IMAGEN
00480 saynow("Writing ");
00481 switch(styp)
00482 { case WF_SBUFF: saytoo(b->b_fn); break;
00483 case WF_SREG: saytoo("region"); break;
00484 #if FX_WLASTKILL
00485 case WF_SKILL: saytoo("last kill"); break;
00486 #endif
00487 }
00488 sayntoo("...");
00489 #else
00490 saynow("Writing...");
00491 #endif
00492
00493 #if !(TOPS20)
00494 if(statres >= 0)
00495 {
00496
00497
00498
00499 chmod(newname,statb.st_mode & 07777);
00500 #if V6
00501 chown(newname, (statb.st_gid<<8)|(statb.st_uid&0377));
00502 #else
00503 chown(newname,statb.st_uid,statb.st_gid);
00504 #endif
00505 }
00506 #if V6
00507
00508
00509
00510
00511
00512 else chmod(newname, ev_filmod);
00513 #endif
00514 #endif
00515
00516
00517 #ifdef STDWRITE
00518 if(flags&WF_ASK)
00519 { switch(styp)
00520 {
00521 case WF_SBUFF:
00522 dotcnt = e_blen();
00523 e_gobob();
00524 break;
00525 case WF_SREG:
00526 if((dotcnt = mark_dot - cur_dot) < 0)
00527 { e_goff(dotcnt);
00528 dotcnt = -dotcnt;
00529 }
00530 else e_gocur();
00531 break;
00532
00533 }
00534 while(--dotcnt >= 0)
00535 putc(sb_getc(((SBBUF *)b)), o_file);
00536 e_gocur();
00537 fflush(o_file);
00538 res = ferror(o_file);
00539 fclose(o_file);
00540 }
00541 else
00542 #endif
00543 {
00544 switch(styp)
00545 {
00546 case WF_SBUFF:
00547 res = sb_fsave((SBBUF *)b, ofd);
00548 break;
00549 case WF_SREG:
00550 e_gocur();
00551 sd = e_copyn((chroff)(mark_dot - cur_dot));
00552 res = sbx_aout(sd, 2, ofd);
00553 sbs_del(sd);
00554 break;
00555 #if FX_WLASTKILL
00556 case WF_SKILL:
00557 res = sbx_aout(kill_ring[kill_ptr], 2, ofd);
00558 break;
00559 #endif
00560 }
00561 close(ofd);
00562 }
00563 if(errno = res)
00564 { ferr(" Output error");
00565 res = 0;
00566 goto wdone;
00567 }
00568 else
00569 res = 1;
00570 if(styp == WF_SBUFF)
00571 f_bufnotmod();
00572
00573
00574
00575 #if TOPS20
00576 saynow("Written");
00577
00578 #else
00579 #if IMAGEN
00580
00581 if ((styp==WF_SBUFF) || !(b->b_flags & B_BACKEDUP))
00582 { if (styp==WF_SBUFF)
00583 b->b_flags |= B_BACKEDUP;
00584 #endif
00585 unlink(oldname);
00586 if(link(o_name,oldname) == 0)
00587 unlink(o_name);
00588
00589
00590
00591 #if IMAGEN
00592 }
00593 else
00594 unlink(o_name);
00595 #endif
00596 if(link(newname,o_name) == 0)
00597 { unlink(newname);
00598 #if IMAGEN
00599 sayntoo("OK");
00600 #else
00601 saynow("Written");
00602 #endif
00603 }
00604 else
00605 { dingtoo("rename error!");
00606 res = 0;
00607 }
00608 #endif
00609
00610 #if IMAGEN
00611
00612 if ((styp == WF_SBUFF) && b->b_fn)
00613 { stat(b->b_fn, &s);
00614 b->b_mtime = s.st_mtime;
00615 }
00616 #endif
00617
00618 wdone:
00619 hoard();
00620 return(res);
00621 }
00622
00623
00624
00625
00626
00627
00628 char *
00629 fncons(dest, pre, f_name, post)
00630 char *dest,*pre,*f_name,*post;
00631 { register char *cp, *cp2;
00632 char *last_fname();
00633
00634 cp = dest;
00635 *cp = 0;
00636 cp2 = last_fname(f_name);
00637 strncat(cp,f_name,cp2-f_name);
00638 if(pre) strcat(cp, pre);
00639 cp = last_fname(cp);
00640 strcat(cp, cp2);
00641 if(cp2 = post)
00642 { cp[FNAMELEN-strlen(cp2)] = 0;
00643 strcat(cp, cp2);
00644 }
00645 return(dest);
00646 }
00647
00648
00649
00650
00651
00652 char *
00653 last_fname(f_name)
00654 char *f_name;
00655 { register char *cp, *p;
00656 register int c;
00657
00658 p = f_name;
00659 cp = p;
00660 while(c = *cp++)
00661 if(c == '/')
00662 p = cp;
00663 return(p);
00664 }
00665
00666
00667
00668
00669 set_fn (string)
00670 char *string;
00671 { register struct buffer *b;
00672 register char *str;
00673 #if IMAGEN
00674 register char *cp;
00675 register int len;
00676 #endif
00677 char *strdup();
00678
00679 b = cur_buf;
00680 str = strdup(string);
00681 if(b->b_fn)
00682 chkfree(b->b_fn);
00683 b -> b_fn = str;
00684 #if IMAGEN
00685
00686 len = strlen(str);
00687 b->b_flags &= ~(B_CMODE|B_TEXTMODE);
00688 if (len > 4)
00689 { if (strcmp(&str[len - 5], "draft") == 0)
00690 b->b_flags |= B_TEXTMODE;
00691 else
00692 { cp = &str[len - 4];
00693 if (strcmp(cp, ".txt") == 0 ||
00694 strcmp(cp, ".mss") == 0)
00695 b->b_flags |= B_TEXTMODE;
00696 }
00697 }
00698 if (len > 2)
00699 { cp = &str[len - 2];
00700 if (strcmp(cp, ".h") == 0 || strcmp(cp, ".c") == 0)
00701 b->b_flags |= B_CMODE;
00702 }
00703 #endif
00704 redp(RD_MODE);
00705 }
00706
00707
00708
00709
00710
00711
00712
00713
00714
00715 saveworld(bp, grunt)
00716 struct buffer *bp;
00717 int grunt;
00718 { register struct buffer *b;
00719 register int wfd;
00720 char sfname[FNAMSIZ];
00721 struct buffer *sel_mbuf();
00722
00723 unhoard();
00724 if(b = bp) goto once;
00725 while(!bp && (b = sel_mbuf(b)))
00726 {
00727 once: strcat(strcat(strcpy(sfname,homedir),"/+"),b->b_name);
00728 if(grunt) printf("Saving %s...",sfname);
00729 #if !(TOPS20)
00730 if((wfd = creat(sfname, ev_filmod)) < 0)
00731 #else
00732 if((wfd = open(sfname,O_WRONLY|O_UNCONVERTED)) < 0)
00733 #endif
00734 { if(grunt)
00735 printf(" error - %s\n", strerror(errno));
00736 }
00737 else
00738 { sb_fsave((SBBUF *)b, wfd);
00739 close(wfd);
00740 if(grunt) printf("\n");
00741 }
00742 b->b_flags &= ~B_MODIFIED;
00743 }
00744 hoard();
00745 }
00746
00747
00748
00749
00750
00751 hoard()
00752 { if(hoardfd <= 0)
00753 #if !(TOPS20)
00754 hoardfd = open("nul:", 1);
00755 #else
00756 hoardfd = open("/dev/null", 1);
00757 #endif
00758 }
00759 unhoard()
00760 { close(hoardfd);
00761 hoardfd = -1;
00762 }
00763
00764 #if IMAGEN
00765 #include <pwd.h>
00766 #include <ctype.h>
00767
00768
00769
00770
00771
00772 expand_file(dfn, sfn)
00773 register char *dfn, *sfn;
00774 {
00775 register char *sp, *tp;
00776 register int c;
00777 register struct passwd *pw;
00778 char ts[128];
00779
00780
00781
00782
00783
00784
00785 if (dfn == sfn)
00786 return;
00787
00788 ts[0] = 0;
00789
00790
00791 if (*sfn == '$')
00792 { ++sfn;
00793 tp = ts;
00794 while (*tp++ = *sfn)
00795 if (!isalnum(*sfn))
00796 break;
00797 else
00798 ++sfn;
00799 *--tp = 0;
00800 strcpy(ts, getenv(ts));
00801 }
00802
00803 else if (*sfn == '~')
00804 { ++sfn;
00805 if (*sfn == '/' || *sfn == 0)
00806 strcpy(ts, getenv("HOME"));
00807 else
00808 { tp = ts;
00809 while (*sfn && *sfn != '/')
00810 *tp++ = *sfn++;
00811 *tp = 0;
00812 pw = (struct passwd *)getpwnam(ts);
00813 if (! pw)
00814 strcpy(ts, "???");
00815 else
00816 strcpy(ts, pw->pw_dir);
00817 }
00818 }
00819
00820
00821
00822
00823 strcpy(dfn, ts);
00824 strcat(dfn, sfn);
00825 }
00826 #endif