17c478bd9Sstevel@tonic-gate /* 27c478bd9Sstevel@tonic-gate * CDDL HEADER START 37c478bd9Sstevel@tonic-gate * 47c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the 5d67944fbSScott Rotondo * Common Development and Distribution License (the "License"). 6d67944fbSScott Rotondo * You may not use this file except in compliance with the License. 77c478bd9Sstevel@tonic-gate * 87c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 97c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 107c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 117c478bd9Sstevel@tonic-gate * and limitations under the License. 127c478bd9Sstevel@tonic-gate * 137c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 147c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 157c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 167c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 177c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 187c478bd9Sstevel@tonic-gate * 197c478bd9Sstevel@tonic-gate * CDDL HEADER END 207c478bd9Sstevel@tonic-gate */ 21*23a1cceaSRoger A. Faulkner 227c478bd9Sstevel@tonic-gate /* 23*23a1cceaSRoger A. Faulkner * Copyright (c) 1989, 2010, Oracle and/or its affiliates. All rights reserved. 247c478bd9Sstevel@tonic-gate */ 257c478bd9Sstevel@tonic-gate 267c478bd9Sstevel@tonic-gate /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ 277c478bd9Sstevel@tonic-gate /* All Rights Reserved */ 287c478bd9Sstevel@tonic-gate 297c478bd9Sstevel@tonic-gate 307c478bd9Sstevel@tonic-gate /* Copyright (c) 1981 Regents of the University of California */ 31f6db9f27Scf46844 327c478bd9Sstevel@tonic-gate #include <stdio.h> /* BUFSIZ: stdio = 1024, VMUNIX = 1024 */ 337c478bd9Sstevel@tonic-gate #ifndef TRACE 347c478bd9Sstevel@tonic-gate #undef NULL 357c478bd9Sstevel@tonic-gate #endif 367c478bd9Sstevel@tonic-gate 377c478bd9Sstevel@tonic-gate #include "ex.h" 387c478bd9Sstevel@tonic-gate #include "ex_temp.h" 397c478bd9Sstevel@tonic-gate #include "ex_tty.h" 407c478bd9Sstevel@tonic-gate #include "ex_tune.h" 417c478bd9Sstevel@tonic-gate #include <pwd.h> 427c478bd9Sstevel@tonic-gate #include <locale.h> 437c478bd9Sstevel@tonic-gate #include <dirent.h> 44ace1a5f1Sdp #include <unistd.h> 45ace1a5f1Sdp #include <errno.h> 46ace1a5f1Sdp 477c478bd9Sstevel@tonic-gate #define DIRSIZ MAXNAMLEN 487c478bd9Sstevel@tonic-gate 497c478bd9Sstevel@tonic-gate short tfile = -1; /* ditto */ 507c478bd9Sstevel@tonic-gate 517c478bd9Sstevel@tonic-gate /* 527c478bd9Sstevel@tonic-gate * 537c478bd9Sstevel@tonic-gate * This program searches through the specified directory and then 547c478bd9Sstevel@tonic-gate * the directory usrpath(preserve) looking for an instance of the specified 557c478bd9Sstevel@tonic-gate * file from a crashed editor or a crashed system. 567c478bd9Sstevel@tonic-gate * If this file is found, it is unscrambled and written to 577c478bd9Sstevel@tonic-gate * the standard output. 587c478bd9Sstevel@tonic-gate * 597c478bd9Sstevel@tonic-gate * If this program terminates without a "broken pipe" diagnostic 607c478bd9Sstevel@tonic-gate * (i.e. the editor doesn't die right away) then the buffer we are 617c478bd9Sstevel@tonic-gate * writing from is removed when we finish. This is potentially a mistake 627c478bd9Sstevel@tonic-gate * as there is not enough handshaking to guarantee that the file has actually 637c478bd9Sstevel@tonic-gate * been recovered, but should suffice for most cases. 647c478bd9Sstevel@tonic-gate */ 657c478bd9Sstevel@tonic-gate 667c478bd9Sstevel@tonic-gate /* 677c478bd9Sstevel@tonic-gate * This directory definition also appears (obviously) in expreserve.c. 687c478bd9Sstevel@tonic-gate * Change both if you change either. 697c478bd9Sstevel@tonic-gate */ 707c478bd9Sstevel@tonic-gate unsigned char mydir[PATH_MAX+1]; 717c478bd9Sstevel@tonic-gate 727c478bd9Sstevel@tonic-gate /* 737c478bd9Sstevel@tonic-gate * Limit on the number of printed entries 747c478bd9Sstevel@tonic-gate * when an, e.g. ``ex -r'' command is given. 757c478bd9Sstevel@tonic-gate */ 767c478bd9Sstevel@tonic-gate #define NENTRY 50 777c478bd9Sstevel@tonic-gate 787c478bd9Sstevel@tonic-gate unsigned char nb[BUFSIZE]; 797c478bd9Sstevel@tonic-gate int vercnt; /* Count number of versions of file found */ 80f6db9f27Scf46844 void rputfile(void); 81f6db9f27Scf46844 void rsyserror(void); 82f6db9f27Scf46844 void searchdir(unsigned char *); 83f6db9f27Scf46844 void scrapbad(void); 84f6db9f27Scf46844 void findtmp(unsigned char *); 85f6db9f27Scf46844 void listfiles(unsigned char *); 86ace1a5f1Sdp 87ace1a5f1Sdp int 88f6db9f27Scf46844 main(int argc, char *argv[]) 897c478bd9Sstevel@tonic-gate { 907c478bd9Sstevel@tonic-gate unsigned char string[50]; 91f6db9f27Scf46844 unsigned char *cp; 92f6db9f27Scf46844 int c, b, i; 93f6db9f27Scf46844 int rflg = 0, errflg = 0; 947c478bd9Sstevel@tonic-gate int label; 957c478bd9Sstevel@tonic-gate line *tmpadr; 967c478bd9Sstevel@tonic-gate extern unsigned char *mypass(); 977c478bd9Sstevel@tonic-gate struct passwd *pp = getpwuid(getuid()); 987c478bd9Sstevel@tonic-gate unsigned char rmcmd[PATH_MAX+1]; 997c478bd9Sstevel@tonic-gate 1007c478bd9Sstevel@tonic-gate (void)setlocale(LC_ALL, ""); 1017c478bd9Sstevel@tonic-gate #if !defined(TEXT_DOMAIN) 1027c478bd9Sstevel@tonic-gate #define TEXT_DOMAIN "SYS_TEST" 1037c478bd9Sstevel@tonic-gate #endif 1047c478bd9Sstevel@tonic-gate (void)textdomain(TEXT_DOMAIN); 1057c478bd9Sstevel@tonic-gate cp = string; 1067c478bd9Sstevel@tonic-gate strcpy(mydir, USRPRESERVE); 1077c478bd9Sstevel@tonic-gate if (pp == NULL) { 1087c478bd9Sstevel@tonic-gate fprintf(stderr, gettext("Unable to get user's id\n")); 1097c478bd9Sstevel@tonic-gate exit(-1); 1107c478bd9Sstevel@tonic-gate } 1117c478bd9Sstevel@tonic-gate strcat(mydir, pp->pw_name); 1127c478bd9Sstevel@tonic-gate 1137c478bd9Sstevel@tonic-gate /* 1147c478bd9Sstevel@tonic-gate * Initialize as though the editor had just started. 1157c478bd9Sstevel@tonic-gate */ 1167c478bd9Sstevel@tonic-gate fendcore = (line *) sbrk(0); 1177c478bd9Sstevel@tonic-gate dot = zero = dol = fendcore; 1187c478bd9Sstevel@tonic-gate one = zero + 1; 1197c478bd9Sstevel@tonic-gate endcore = fendcore - 2; 1207c478bd9Sstevel@tonic-gate iblock = oblock = -1; 1217c478bd9Sstevel@tonic-gate 1227c478bd9Sstevel@tonic-gate while ((c=getopt(argc, (char **)argv, "rx")) != EOF) 1237c478bd9Sstevel@tonic-gate switch (c) { 1247c478bd9Sstevel@tonic-gate case 'r': 1257c478bd9Sstevel@tonic-gate rflg++; 1267c478bd9Sstevel@tonic-gate break; 1277c478bd9Sstevel@tonic-gate 1287c478bd9Sstevel@tonic-gate case 'x': 1297c478bd9Sstevel@tonic-gate xflag++; 1307c478bd9Sstevel@tonic-gate break; 1317c478bd9Sstevel@tonic-gate 1327c478bd9Sstevel@tonic-gate case '?': 1337c478bd9Sstevel@tonic-gate errflg++; 1347c478bd9Sstevel@tonic-gate break; 1357c478bd9Sstevel@tonic-gate } 1367c478bd9Sstevel@tonic-gate argc -= optind; 1377c478bd9Sstevel@tonic-gate argv = &argv[optind]; 1387c478bd9Sstevel@tonic-gate 1397c478bd9Sstevel@tonic-gate if (errflg) 1407c478bd9Sstevel@tonic-gate exit(2); 1417c478bd9Sstevel@tonic-gate 1427c478bd9Sstevel@tonic-gate /* 1437c478bd9Sstevel@tonic-gate * If given only a -r argument, then list the saved files. 1447c478bd9Sstevel@tonic-gate * (NOTE: single -r argument is scheduled to be replaced by -L). 1457c478bd9Sstevel@tonic-gate */ 1467c478bd9Sstevel@tonic-gate if (rflg && argc == 0) { 1477c478bd9Sstevel@tonic-gate fprintf(stderr,"%s:\n", mydir); 1487c478bd9Sstevel@tonic-gate listfiles(mydir); 1497c478bd9Sstevel@tonic-gate fprintf(stderr,"%s:\n", TMPDIR); 150f6db9f27Scf46844 listfiles((unsigned char *)TMPDIR); 1517c478bd9Sstevel@tonic-gate exit(0); 1527c478bd9Sstevel@tonic-gate } 1537c478bd9Sstevel@tonic-gate 1547c478bd9Sstevel@tonic-gate if (argc != 2) 1557c478bd9Sstevel@tonic-gate error(gettext(" Wrong number of arguments to exrecover"), 0); 1567c478bd9Sstevel@tonic-gate 1577c478bd9Sstevel@tonic-gate CP(file, argv[1]); 1587c478bd9Sstevel@tonic-gate 1597c478bd9Sstevel@tonic-gate /* 1607c478bd9Sstevel@tonic-gate * Search for this file. 1617c478bd9Sstevel@tonic-gate */ 162f6db9f27Scf46844 findtmp((unsigned char *)argv[0]); 1637c478bd9Sstevel@tonic-gate 1647c478bd9Sstevel@tonic-gate /* 1657c478bd9Sstevel@tonic-gate * Got (one of the versions of) it, write it back to the editor. 1667c478bd9Sstevel@tonic-gate */ 1677c478bd9Sstevel@tonic-gate (void)cftime((char *)cp, "%a %h %d %T", &H.Time); 1687c478bd9Sstevel@tonic-gate fprintf(stderr, vercnt > 1 ? 1697c478bd9Sstevel@tonic-gate gettext(" [Dated: %s, newest of %d saved]") : 1707c478bd9Sstevel@tonic-gate gettext(" [Dated: %s]"), cp, vercnt); 1717c478bd9Sstevel@tonic-gate fprintf(stderr, "\r\n"); 1727c478bd9Sstevel@tonic-gate 1737c478bd9Sstevel@tonic-gate if(H.encrypted) { 1747c478bd9Sstevel@tonic-gate if(xflag) { 1757c478bd9Sstevel@tonic-gate kflag = run_setkey(perm, (unsigned char *)getenv("CrYpTkEy")); 1767c478bd9Sstevel@tonic-gate } else 1777c478bd9Sstevel@tonic-gate kflag = run_setkey(perm, mypass("Enter key:")); 1787c478bd9Sstevel@tonic-gate if(kflag == -1) { 1797c478bd9Sstevel@tonic-gate kflag = 0; 1807c478bd9Sstevel@tonic-gate xflag = 0; 1817c478bd9Sstevel@tonic-gate fprintf(stderr,gettext("Encryption facility not available\n")); 1827c478bd9Sstevel@tonic-gate exit(-1); 1837c478bd9Sstevel@tonic-gate } 1847c478bd9Sstevel@tonic-gate xtflag = 1; 1857c478bd9Sstevel@tonic-gate if (makekey(tperm) != 0) { 1867c478bd9Sstevel@tonic-gate xtflag = 0; 1877c478bd9Sstevel@tonic-gate fprintf(stderr,gettext("Warning--Cannot encrypt temporary buffer\n")); 1887c478bd9Sstevel@tonic-gate exit(-1); 1897c478bd9Sstevel@tonic-gate } 1907c478bd9Sstevel@tonic-gate } 1917c478bd9Sstevel@tonic-gate fprintf(stderr,gettext("\r\n [Hit return to continue]")); 1927c478bd9Sstevel@tonic-gate fflush(stderr); 1937c478bd9Sstevel@tonic-gate setbuf(stdin, (char *)NULL); 1947c478bd9Sstevel@tonic-gate while((c = getchar()) != '\n' && c != '\r'); 1957c478bd9Sstevel@tonic-gate H.Flines++; 1967c478bd9Sstevel@tonic-gate 1977c478bd9Sstevel@tonic-gate /* 1987c478bd9Sstevel@tonic-gate * Allocate space for the line pointers from the temp file. 1997c478bd9Sstevel@tonic-gate */ 2007c478bd9Sstevel@tonic-gate if ((int) sbrk((int) (H.Flines * sizeof (line))) == -1) 2017c478bd9Sstevel@tonic-gate error(gettext(" Not enough core for lines"), 0); 2027c478bd9Sstevel@tonic-gate #ifdef DEBUG 2037c478bd9Sstevel@tonic-gate fprintf(stderr, "%d lines\n", H.Flines); 2047c478bd9Sstevel@tonic-gate #endif 2057c478bd9Sstevel@tonic-gate 2067c478bd9Sstevel@tonic-gate /* 2077c478bd9Sstevel@tonic-gate * Now go get the blocks of seek pointers which are scattered 2087c478bd9Sstevel@tonic-gate * throughout the temp file, reconstructing the incore 2097c478bd9Sstevel@tonic-gate * line pointers at point of crash. 2107c478bd9Sstevel@tonic-gate */ 2117c478bd9Sstevel@tonic-gate b = 0; 2127c478bd9Sstevel@tonic-gate while (H.Flines > 0) { 2137c478bd9Sstevel@tonic-gate (void)lseek(tfile, (long) blocks[b] * BUFSIZE, 0); 2147c478bd9Sstevel@tonic-gate i = H.Flines < BUFSIZE / sizeof (line) ? 2157c478bd9Sstevel@tonic-gate H.Flines * sizeof (line) : BUFSIZE; 2167c478bd9Sstevel@tonic-gate if (read(tfile, (char *) dot, i) != i) { 2177c478bd9Sstevel@tonic-gate perror((char *)nb); 2187c478bd9Sstevel@tonic-gate exit(1); 2197c478bd9Sstevel@tonic-gate } 2207c478bd9Sstevel@tonic-gate dot += i / sizeof (line); 2217c478bd9Sstevel@tonic-gate H.Flines -= i / sizeof (line); 2227c478bd9Sstevel@tonic-gate b++; 2237c478bd9Sstevel@tonic-gate } 2247c478bd9Sstevel@tonic-gate dot--; dol = dot; 2257c478bd9Sstevel@tonic-gate 2267c478bd9Sstevel@tonic-gate /* 2277c478bd9Sstevel@tonic-gate * Due to sandbagging some lines may really not be there. 2287c478bd9Sstevel@tonic-gate * Find and discard such. This shouldn't happen often. 2297c478bd9Sstevel@tonic-gate */ 2307c478bd9Sstevel@tonic-gate scrapbad(); 2317c478bd9Sstevel@tonic-gate 2327c478bd9Sstevel@tonic-gate 2337c478bd9Sstevel@tonic-gate /* 2347c478bd9Sstevel@tonic-gate * Now if there were any lines in the recovered file 2357c478bd9Sstevel@tonic-gate * write them to the standard output. 2367c478bd9Sstevel@tonic-gate */ 2377c478bd9Sstevel@tonic-gate if (dol > zero) { 2387c478bd9Sstevel@tonic-gate addr1 = one; addr2 = dol; io = 1; 239f6db9f27Scf46844 rputfile(); 2407c478bd9Sstevel@tonic-gate } 2417c478bd9Sstevel@tonic-gate /* 2427c478bd9Sstevel@tonic-gate * Trash the saved buffer. 2437c478bd9Sstevel@tonic-gate * Hopefully the system won't crash before the editor 2447c478bd9Sstevel@tonic-gate * syncs the new recovered buffer; i.e. for an instant here 2457c478bd9Sstevel@tonic-gate * you may lose if the system crashes because this file 2467c478bd9Sstevel@tonic-gate * is gone, but the editor hasn't completed reading the recovered 2477c478bd9Sstevel@tonic-gate * file from the pipe from us to it. 2487c478bd9Sstevel@tonic-gate * 2497c478bd9Sstevel@tonic-gate * This doesn't work if we are coming from an non-absolute path 2507c478bd9Sstevel@tonic-gate * name since we may have chdir'ed but what the hay, noone really 2517c478bd9Sstevel@tonic-gate * ever edits with temporaries in "." anyways. 2527c478bd9Sstevel@tonic-gate */ 2537c478bd9Sstevel@tonic-gate if (nb[0] == '/') { 254ace1a5f1Sdp (void)unlink((const char *)nb); 2557c478bd9Sstevel@tonic-gate sprintf((char *)rmcmd, "rmdir %s 2> /dev/null", (char *)mydir); 2567c478bd9Sstevel@tonic-gate system((char *)rmcmd); 2577c478bd9Sstevel@tonic-gate } 258f6db9f27Scf46844 return (0); 2597c478bd9Sstevel@tonic-gate } 2607c478bd9Sstevel@tonic-gate 2617c478bd9Sstevel@tonic-gate /* 2627c478bd9Sstevel@tonic-gate * Print an error message (notably not in error 2637c478bd9Sstevel@tonic-gate * message file). If terminal is in RAW mode, then 2647c478bd9Sstevel@tonic-gate * we should be writing output for "vi", so don't print 2657c478bd9Sstevel@tonic-gate * a newline which would mess up the screen. 2667c478bd9Sstevel@tonic-gate */ 2677c478bd9Sstevel@tonic-gate /*VARARGS2*/ 268f6db9f27Scf46844 void 2697c478bd9Sstevel@tonic-gate error(str, inf) 2707c478bd9Sstevel@tonic-gate unsigned char *str; 2717c478bd9Sstevel@tonic-gate int inf; 2727c478bd9Sstevel@tonic-gate { 2737c478bd9Sstevel@tonic-gate 2747c478bd9Sstevel@tonic-gate struct termio termio; 2757c478bd9Sstevel@tonic-gate if (inf) 2767c478bd9Sstevel@tonic-gate fprintf(stderr, (char *)str, inf); 2777c478bd9Sstevel@tonic-gate else 2787c478bd9Sstevel@tonic-gate fprintf(stderr, (char *)str); 2797c478bd9Sstevel@tonic-gate 2807c478bd9Sstevel@tonic-gate ioctl(2, TCGETA, &termio); 2817c478bd9Sstevel@tonic-gate if (termio.c_lflag & ICANON) 2827c478bd9Sstevel@tonic-gate fprintf(stderr, "\n"); 2837c478bd9Sstevel@tonic-gate exit(1); 2847c478bd9Sstevel@tonic-gate } 2857c478bd9Sstevel@tonic-gate 2867c478bd9Sstevel@tonic-gate /* 2877c478bd9Sstevel@tonic-gate * Here we save the information about files, when 2887c478bd9Sstevel@tonic-gate * you ask us what files we have saved for you. 2897c478bd9Sstevel@tonic-gate * We buffer file name, number of lines, and the time 2907c478bd9Sstevel@tonic-gate * at which the file was saved. 2917c478bd9Sstevel@tonic-gate */ 2927c478bd9Sstevel@tonic-gate struct svfile { 2937c478bd9Sstevel@tonic-gate unsigned char sf_name[FNSIZE + 1]; 2947c478bd9Sstevel@tonic-gate int sf_lines; 2957c478bd9Sstevel@tonic-gate unsigned char sf_entry[DIRSIZ + 1]; 2967c478bd9Sstevel@tonic-gate time_t sf_time; 2977c478bd9Sstevel@tonic-gate short sf_encrypted; 2987c478bd9Sstevel@tonic-gate }; 299f6db9f27Scf46844 void enter(struct svfile *, unsigned char *, int); 3007c478bd9Sstevel@tonic-gate 301f6db9f27Scf46844 void 302f6db9f27Scf46844 listfiles(unsigned char *dirname) 3037c478bd9Sstevel@tonic-gate { 304f6db9f27Scf46844 DIR *dir; 3057c478bd9Sstevel@tonic-gate struct dirent64 *direntry; 3067c478bd9Sstevel@tonic-gate int ecount, qucmp(); 307f6db9f27Scf46844 int f; 3087c478bd9Sstevel@tonic-gate unsigned char cp[50]; 3097c478bd9Sstevel@tonic-gate unsigned char cp2[50]; 3107c478bd9Sstevel@tonic-gate unsigned char *filname; 3117c478bd9Sstevel@tonic-gate struct svfile *fp, svbuf[NENTRY]; 3127c478bd9Sstevel@tonic-gate 3137c478bd9Sstevel@tonic-gate /* 3147c478bd9Sstevel@tonic-gate * Open usrpath(preserve), and go there to make things quick. 3157c478bd9Sstevel@tonic-gate */ 3167c478bd9Sstevel@tonic-gate if ((dir = opendir((char *)dirname)) == NULL) 3177c478bd9Sstevel@tonic-gate { 3187c478bd9Sstevel@tonic-gate fprintf(stderr,gettext("No files saved.\n")); 3197c478bd9Sstevel@tonic-gate return; 3207c478bd9Sstevel@tonic-gate } 321ace1a5f1Sdp if (chdir((const char *)dirname) < 0) { 3227c478bd9Sstevel@tonic-gate perror((char *)dirname); 3237c478bd9Sstevel@tonic-gate return; 3247c478bd9Sstevel@tonic-gate } 3257c478bd9Sstevel@tonic-gate 3267c478bd9Sstevel@tonic-gate /* 3277c478bd9Sstevel@tonic-gate * Look at the candidate files in usrpath(preserve). 3287c478bd9Sstevel@tonic-gate */ 3297c478bd9Sstevel@tonic-gate fp = &svbuf[0]; 3307c478bd9Sstevel@tonic-gate ecount = 0; 3317c478bd9Sstevel@tonic-gate while ((direntry = readdir64(dir)) != NULL) 3327c478bd9Sstevel@tonic-gate { 3337c478bd9Sstevel@tonic-gate filname = (unsigned char *)direntry->d_name; 3347c478bd9Sstevel@tonic-gate if (filname[0] != 'E') 3357c478bd9Sstevel@tonic-gate continue; 3367c478bd9Sstevel@tonic-gate #ifdef DEBUG 3377c478bd9Sstevel@tonic-gate fprintf(stderr, "considering %s\n", filname); 3387c478bd9Sstevel@tonic-gate #endif 3397c478bd9Sstevel@tonic-gate /* 3407c478bd9Sstevel@tonic-gate * Name begins with E; open it and 3417c478bd9Sstevel@tonic-gate * make sure the uid in the header is our uid. 3427c478bd9Sstevel@tonic-gate * If not, then don't bother with this file, it can't 3437c478bd9Sstevel@tonic-gate * be ours. 3447c478bd9Sstevel@tonic-gate */ 3457c478bd9Sstevel@tonic-gate f = open(filname, 0); 3467c478bd9Sstevel@tonic-gate if (f < 0) { 3477c478bd9Sstevel@tonic-gate #ifdef DEBUG 3487c478bd9Sstevel@tonic-gate fprintf(stderr, "open failed\n"); 3497c478bd9Sstevel@tonic-gate #endif 3507c478bd9Sstevel@tonic-gate continue; 3517c478bd9Sstevel@tonic-gate } 3527c478bd9Sstevel@tonic-gate if (read(f, (char *) &H, sizeof H) != sizeof H) { 3537c478bd9Sstevel@tonic-gate #ifdef DEBUG 3547c478bd9Sstevel@tonic-gate fprintf(stderr, "could not read header\n"); 3557c478bd9Sstevel@tonic-gate #endif 3567c478bd9Sstevel@tonic-gate (void)close(f); 3577c478bd9Sstevel@tonic-gate continue; 3587c478bd9Sstevel@tonic-gate } 3597c478bd9Sstevel@tonic-gate (void)close(f); 3607c478bd9Sstevel@tonic-gate if (getuid() != H.Uid) { 3617c478bd9Sstevel@tonic-gate #ifdef DEBUG 3627c478bd9Sstevel@tonic-gate fprintf(stderr, "uid wrong\n"); 3637c478bd9Sstevel@tonic-gate #endif 3647c478bd9Sstevel@tonic-gate continue; 3657c478bd9Sstevel@tonic-gate } 3667c478bd9Sstevel@tonic-gate 3677c478bd9Sstevel@tonic-gate /* 3687c478bd9Sstevel@tonic-gate * Saved the day! 3697c478bd9Sstevel@tonic-gate */ 3707c478bd9Sstevel@tonic-gate enter(fp++, filname, ecount); 3717c478bd9Sstevel@tonic-gate ecount++; 3727c478bd9Sstevel@tonic-gate #ifdef DEBUG 3737c478bd9Sstevel@tonic-gate fprintf(stderr, "entered file %s\n", filname); 3747c478bd9Sstevel@tonic-gate #endif 3757c478bd9Sstevel@tonic-gate } 3767c478bd9Sstevel@tonic-gate (void)closedir(dir); 3777c478bd9Sstevel@tonic-gate /* 3787c478bd9Sstevel@tonic-gate * If any files were saved, then sort them and print 3797c478bd9Sstevel@tonic-gate * them out. 3807c478bd9Sstevel@tonic-gate */ 3817c478bd9Sstevel@tonic-gate if (ecount == 0) { 3827c478bd9Sstevel@tonic-gate fprintf(stderr, gettext("No files saved.\n")); 3837c478bd9Sstevel@tonic-gate return; 3847c478bd9Sstevel@tonic-gate } 3857c478bd9Sstevel@tonic-gate qsort(&svbuf[0], ecount, sizeof svbuf[0], qucmp); 3867c478bd9Sstevel@tonic-gate for (fp = &svbuf[0]; fp < &svbuf[ecount]; fp++) { 3877c478bd9Sstevel@tonic-gate (void)cftime((char *)cp, "%a %b %d", &fp->sf_time); 3887c478bd9Sstevel@tonic-gate (void)cftime((char *)cp2, "%R", &fp->sf_time); 3897c478bd9Sstevel@tonic-gate fprintf(stderr, 3907c478bd9Sstevel@tonic-gate gettext("On %s at %s, saved %d lines of file \"%s\" "), 3917c478bd9Sstevel@tonic-gate cp, cp2, fp->sf_lines, fp->sf_name); 3927c478bd9Sstevel@tonic-gate fprintf(stderr, "%s\n", 3937c478bd9Sstevel@tonic-gate (fp->sf_encrypted) ? gettext("[ENCRYPTED]") : ""); 3947c478bd9Sstevel@tonic-gate } 3957c478bd9Sstevel@tonic-gate } 3967c478bd9Sstevel@tonic-gate 3977c478bd9Sstevel@tonic-gate /* 3987c478bd9Sstevel@tonic-gate * Enter a new file into the saved file information. 3997c478bd9Sstevel@tonic-gate */ 400f6db9f27Scf46844 void 401f6db9f27Scf46844 enter(struct svfile *fp, unsigned char *fname, int count) 4027c478bd9Sstevel@tonic-gate { 403f6db9f27Scf46844 unsigned char *cp, *cp2; 404f6db9f27Scf46844 struct svfile *f, *fl; 4057c478bd9Sstevel@tonic-gate time_t curtime; 4067c478bd9Sstevel@tonic-gate 4077c478bd9Sstevel@tonic-gate f = 0; 4087c478bd9Sstevel@tonic-gate if (count >= NENTRY) { 4097c478bd9Sstevel@tonic-gate /* 4107c478bd9Sstevel@tonic-gate * Trash the oldest as the most useless. 4117c478bd9Sstevel@tonic-gate */ 4127c478bd9Sstevel@tonic-gate fl = fp - count + NENTRY - 1; 4137c478bd9Sstevel@tonic-gate curtime = fl->sf_time; 4147c478bd9Sstevel@tonic-gate for (f = fl; --f > fp-count; ) 4157c478bd9Sstevel@tonic-gate if (f->sf_time < curtime) 4167c478bd9Sstevel@tonic-gate curtime = f->sf_time; 4177c478bd9Sstevel@tonic-gate for (f = fl; --f > fp-count; ) 4187c478bd9Sstevel@tonic-gate if (f->sf_time == curtime) 4197c478bd9Sstevel@tonic-gate break; 4207c478bd9Sstevel@tonic-gate fp = f; 4217c478bd9Sstevel@tonic-gate } 4227c478bd9Sstevel@tonic-gate 4237c478bd9Sstevel@tonic-gate /* 4247c478bd9Sstevel@tonic-gate * Gotcha. 4257c478bd9Sstevel@tonic-gate */ 4267c478bd9Sstevel@tonic-gate fp->sf_time = H.Time; 4277c478bd9Sstevel@tonic-gate fp->sf_lines = H.Flines; 4287c478bd9Sstevel@tonic-gate fp->sf_encrypted = H.encrypted; 4297c478bd9Sstevel@tonic-gate for (cp2 = fp->sf_name, cp = savedfile; *cp;) 4307c478bd9Sstevel@tonic-gate *cp2++ = *cp++; 4317c478bd9Sstevel@tonic-gate *cp2++ = 0; 4327c478bd9Sstevel@tonic-gate for (cp2 = fp->sf_entry, cp = fname; *cp && cp-fname < 14;) 4337c478bd9Sstevel@tonic-gate *cp2++ = *cp++; 4347c478bd9Sstevel@tonic-gate *cp2++ = 0; 4357c478bd9Sstevel@tonic-gate } 4367c478bd9Sstevel@tonic-gate 4377c478bd9Sstevel@tonic-gate /* 4387c478bd9Sstevel@tonic-gate * Do the qsort compare to sort the entries first by file name, 4397c478bd9Sstevel@tonic-gate * then by modify time. 4407c478bd9Sstevel@tonic-gate */ 441f6db9f27Scf46844 int 442f6db9f27Scf46844 qucmp(struct svfile *p1, struct svfile *p2) 4437c478bd9Sstevel@tonic-gate { 444f6db9f27Scf46844 int t; 4457c478bd9Sstevel@tonic-gate 4467c478bd9Sstevel@tonic-gate if (t = strcmp(p1->sf_name, p2->sf_name)) 4477c478bd9Sstevel@tonic-gate return(t); 4487c478bd9Sstevel@tonic-gate if (p1->sf_time > p2->sf_time) 4497c478bd9Sstevel@tonic-gate return(-1); 4507c478bd9Sstevel@tonic-gate return(p1->sf_time < p2->sf_time); 4517c478bd9Sstevel@tonic-gate } 4527c478bd9Sstevel@tonic-gate 4537c478bd9Sstevel@tonic-gate /* 4547c478bd9Sstevel@tonic-gate * Scratch for search. 4557c478bd9Sstevel@tonic-gate */ 4567c478bd9Sstevel@tonic-gate unsigned char bestnb[BUFSIZE]; /* Name of the best one */ 4577c478bd9Sstevel@tonic-gate long besttime = 0; /* Time at which the best file was saved */ 4587c478bd9Sstevel@tonic-gate int bestfd; /* Keep best file open so it dont vanish */ 4597c478bd9Sstevel@tonic-gate 4607c478bd9Sstevel@tonic-gate /* 4617c478bd9Sstevel@tonic-gate * Look for a file, both in the users directory option value 4627c478bd9Sstevel@tonic-gate * (i.e. usually /tmp) and in usrpath(preserve). 4637c478bd9Sstevel@tonic-gate * Want to find the newest so we search on and on. 4647c478bd9Sstevel@tonic-gate */ 465f6db9f27Scf46844 void 466f6db9f27Scf46844 findtmp(unsigned char *dir) 4677c478bd9Sstevel@tonic-gate { 4687c478bd9Sstevel@tonic-gate 4697c478bd9Sstevel@tonic-gate /* 4707c478bd9Sstevel@tonic-gate * No name or file so far. 4717c478bd9Sstevel@tonic-gate */ 4727c478bd9Sstevel@tonic-gate bestnb[0] = 0; 4737c478bd9Sstevel@tonic-gate bestfd = -1; 4747c478bd9Sstevel@tonic-gate 4757c478bd9Sstevel@tonic-gate /* 4767c478bd9Sstevel@tonic-gate * Search usrpath(preserve) and, if we can get there, /tmp 4777c478bd9Sstevel@tonic-gate * (actually the user's "directory" option). 4787c478bd9Sstevel@tonic-gate */ 4797c478bd9Sstevel@tonic-gate searchdir(dir); 480ace1a5f1Sdp if (chdir((const char *)mydir) == 0) 4817c478bd9Sstevel@tonic-gate searchdir(mydir); 4827c478bd9Sstevel@tonic-gate if (bestfd != -1) { 4837c478bd9Sstevel@tonic-gate /* 4847c478bd9Sstevel@tonic-gate * Gotcha. 4857c478bd9Sstevel@tonic-gate * Put the file (which is already open) in the file 4867c478bd9Sstevel@tonic-gate * used by the temp file routines, and save its 4877c478bd9Sstevel@tonic-gate * name for later unlinking. 4887c478bd9Sstevel@tonic-gate */ 4897c478bd9Sstevel@tonic-gate tfile = bestfd; 4907c478bd9Sstevel@tonic-gate CP(nb, bestnb); 4917c478bd9Sstevel@tonic-gate (void)lseek(tfile, 0l, 0); 4927c478bd9Sstevel@tonic-gate 4937c478bd9Sstevel@tonic-gate /* 4947c478bd9Sstevel@tonic-gate * Gotta be able to read the header or fall through 4957c478bd9Sstevel@tonic-gate * to lossage. 4967c478bd9Sstevel@tonic-gate */ 4977c478bd9Sstevel@tonic-gate if (read(tfile, (char *) &H, sizeof H) == sizeof H) 4987c478bd9Sstevel@tonic-gate return; 4997c478bd9Sstevel@tonic-gate } 5007c478bd9Sstevel@tonic-gate 5017c478bd9Sstevel@tonic-gate /* 5027c478bd9Sstevel@tonic-gate * Extreme lossage... 5037c478bd9Sstevel@tonic-gate */ 504f6db9f27Scf46844 error((unsigned char *)gettext(" File not found"), 0); 5057c478bd9Sstevel@tonic-gate } 5067c478bd9Sstevel@tonic-gate 5077c478bd9Sstevel@tonic-gate /* 5087c478bd9Sstevel@tonic-gate * Search for the file in directory dirname. 5097c478bd9Sstevel@tonic-gate * 5107c478bd9Sstevel@tonic-gate * Don't chdir here, because the users directory 5117c478bd9Sstevel@tonic-gate * may be ".", and we would move away before we searched it. 5127c478bd9Sstevel@tonic-gate * Note that we actually chdir elsewhere (because it is too slow 5137c478bd9Sstevel@tonic-gate * to look around in usrpath(preserve) without chdir'ing there) so we 5147c478bd9Sstevel@tonic-gate * can't win, because we don't know the name of '.' and if the path 5157c478bd9Sstevel@tonic-gate * name of the file we want to unlink is relative, rather than absolute 5167c478bd9Sstevel@tonic-gate * we won't be able to find it again. 5177c478bd9Sstevel@tonic-gate */ 518f6db9f27Scf46844 void 519f6db9f27Scf46844 searchdir(unsigned char *dirname) 5207c478bd9Sstevel@tonic-gate { 5217c478bd9Sstevel@tonic-gate struct dirent64 *direntry; 522f6db9f27Scf46844 DIR *dir; 5237c478bd9Sstevel@tonic-gate unsigned char dbuf[BUFSIZE]; 5247c478bd9Sstevel@tonic-gate unsigned char *filname; 5257c478bd9Sstevel@tonic-gate if ((dir = opendir((char *)dirname)) == NULL) 5267c478bd9Sstevel@tonic-gate return; 5277c478bd9Sstevel@tonic-gate while ((direntry = readdir64(dir)) != NULL) 5287c478bd9Sstevel@tonic-gate { 5297c478bd9Sstevel@tonic-gate filname = (unsigned char *)direntry->d_name; 5307c478bd9Sstevel@tonic-gate if (filname[0] != 'E' || filname[1] != 'x') 5317c478bd9Sstevel@tonic-gate continue; 5327c478bd9Sstevel@tonic-gate /* 5337c478bd9Sstevel@tonic-gate * Got a file in the directory starting with Ex... 5347c478bd9Sstevel@tonic-gate * Save a consed up name for the file to unlink 5357c478bd9Sstevel@tonic-gate * later, and check that this is really a file 5367c478bd9Sstevel@tonic-gate * we are looking for. 5377c478bd9Sstevel@tonic-gate */ 5387c478bd9Sstevel@tonic-gate (void)strcat(strcat(strcpy(nb, dirname), "/"), filname); 5397c478bd9Sstevel@tonic-gate if (yeah(nb)) { 5407c478bd9Sstevel@tonic-gate /* 5417c478bd9Sstevel@tonic-gate * Well, it is the file we are looking for. 5427c478bd9Sstevel@tonic-gate * Is it more recent than any version we found before? 5437c478bd9Sstevel@tonic-gate */ 5447c478bd9Sstevel@tonic-gate if (H.Time > besttime) { 5457c478bd9Sstevel@tonic-gate /* 5467c478bd9Sstevel@tonic-gate * A winner. 5477c478bd9Sstevel@tonic-gate */ 5487c478bd9Sstevel@tonic-gate (void)close(bestfd); 5497c478bd9Sstevel@tonic-gate bestfd = dup(tfile); 5507c478bd9Sstevel@tonic-gate besttime = H.Time; 5517c478bd9Sstevel@tonic-gate CP(bestnb, nb); 5527c478bd9Sstevel@tonic-gate } 5537c478bd9Sstevel@tonic-gate /* 5547c478bd9Sstevel@tonic-gate * Count versions and tell user 5557c478bd9Sstevel@tonic-gate */ 5567c478bd9Sstevel@tonic-gate vercnt++; 5577c478bd9Sstevel@tonic-gate } 5587c478bd9Sstevel@tonic-gate (void)close(tfile); 5597c478bd9Sstevel@tonic-gate } 5607c478bd9Sstevel@tonic-gate (void)closedir(dir); 5617c478bd9Sstevel@tonic-gate } 5627c478bd9Sstevel@tonic-gate 5637c478bd9Sstevel@tonic-gate /* 5647c478bd9Sstevel@tonic-gate * Given a candidate file to be recovered, see 5657c478bd9Sstevel@tonic-gate * if it's really an editor temporary and of this 5667c478bd9Sstevel@tonic-gate * user and the file specified. 5677c478bd9Sstevel@tonic-gate */ 568f6db9f27Scf46844 int 569f6db9f27Scf46844 yeah(unsigned char *name) 5707c478bd9Sstevel@tonic-gate { 5717c478bd9Sstevel@tonic-gate 5727c478bd9Sstevel@tonic-gate tfile = open(name, 2); 5737c478bd9Sstevel@tonic-gate if (tfile < 0) 5747c478bd9Sstevel@tonic-gate return (0); 5757c478bd9Sstevel@tonic-gate if (read(tfile, (char *) &H, sizeof H) != sizeof H) { 5767c478bd9Sstevel@tonic-gate nope: 5777c478bd9Sstevel@tonic-gate (void)close(tfile); 5787c478bd9Sstevel@tonic-gate return (0); 5797c478bd9Sstevel@tonic-gate } 5807c478bd9Sstevel@tonic-gate if (!eq(savedfile, file)) 5817c478bd9Sstevel@tonic-gate goto nope; 5827c478bd9Sstevel@tonic-gate if (getuid() != H.Uid) 5837c478bd9Sstevel@tonic-gate goto nope; 5847c478bd9Sstevel@tonic-gate /* 5857c478bd9Sstevel@tonic-gate * Old code: puts a word LOST in the header block, so that lost lines 5867c478bd9Sstevel@tonic-gate * can be made to point at it. 5877c478bd9Sstevel@tonic-gate */ 5887c478bd9Sstevel@tonic-gate (void)lseek(tfile, (long)(BUFSIZE*HBLKS-8), 0); 5897c478bd9Sstevel@tonic-gate (void)write(tfile, "LOST", 5); 5907c478bd9Sstevel@tonic-gate return (1); 5917c478bd9Sstevel@tonic-gate } 5927c478bd9Sstevel@tonic-gate 5937c478bd9Sstevel@tonic-gate /* 5947c478bd9Sstevel@tonic-gate * Find the true end of the scratch file, and ``LOSE'' 5957c478bd9Sstevel@tonic-gate * lines which point into thin air. This lossage occurs 5967c478bd9Sstevel@tonic-gate * due to the sandbagging of i/o which can cause blocks to 5977c478bd9Sstevel@tonic-gate * be written in a non-obvious order, different from the order 5987c478bd9Sstevel@tonic-gate * in which the editor tried to write them. 5997c478bd9Sstevel@tonic-gate * 6007c478bd9Sstevel@tonic-gate * Lines which are lost are replaced with the text LOST so 6017c478bd9Sstevel@tonic-gate * they are easy to find. We work hard at pretty formatting here 6027c478bd9Sstevel@tonic-gate * as lines tend to be lost in blocks. 6037c478bd9Sstevel@tonic-gate * 6047c478bd9Sstevel@tonic-gate * This only seems to happen on very heavily loaded systems, and 6057c478bd9Sstevel@tonic-gate * not very often. 6067c478bd9Sstevel@tonic-gate */ 607f6db9f27Scf46844 void 608f6db9f27Scf46844 scrapbad(void) 6097c478bd9Sstevel@tonic-gate { 610f6db9f27Scf46844 line *ip; 6117c478bd9Sstevel@tonic-gate struct stat64 stbuf; 6127c478bd9Sstevel@tonic-gate off_t size, maxt; 6137c478bd9Sstevel@tonic-gate int bno, cnt, bad, was; 6147c478bd9Sstevel@tonic-gate unsigned char bk[BUFSIZE]; 6157c478bd9Sstevel@tonic-gate 6167c478bd9Sstevel@tonic-gate (void)fstat64(tfile, &stbuf); 6177c478bd9Sstevel@tonic-gate size = (off_t)stbuf.st_size; 6187c478bd9Sstevel@tonic-gate maxt = (size >> SHFT) | (BNDRY-1); 6197c478bd9Sstevel@tonic-gate bno = (maxt >> OFFBTS) & BLKMSK; 6207c478bd9Sstevel@tonic-gate #ifdef DEBUG 6217c478bd9Sstevel@tonic-gate fprintf(stderr, "size %ld, maxt %o, bno %d\n", size, maxt, bno); 6227c478bd9Sstevel@tonic-gate #endif 6237c478bd9Sstevel@tonic-gate 6247c478bd9Sstevel@tonic-gate /* 6257c478bd9Sstevel@tonic-gate * Look for a null separating two lines in the temp file; 6267c478bd9Sstevel@tonic-gate * if last line was split across blocks, then it is lost 6277c478bd9Sstevel@tonic-gate * if the last block is. 6287c478bd9Sstevel@tonic-gate */ 6297c478bd9Sstevel@tonic-gate while (bno > 0) { 6307c478bd9Sstevel@tonic-gate (void)lseek(tfile, (long) BUFSIZE * bno, 0); 6317c478bd9Sstevel@tonic-gate cnt = read(tfile, (char *) bk, BUFSIZE); 6327c478bd9Sstevel@tonic-gate if(xtflag) 6337c478bd9Sstevel@tonic-gate if (run_crypt(0L, bk, CRSIZE, tperm) == -1) 634f6db9f27Scf46844 rsyserror(); 6357c478bd9Sstevel@tonic-gate #ifdef DEBUG 6367c478bd9Sstevel@tonic-gate fprintf(stderr,"UNENCRYPTED: BLK %d\n",bno); 6377c478bd9Sstevel@tonic-gate #endif 6387c478bd9Sstevel@tonic-gate while (cnt > 0) 6397c478bd9Sstevel@tonic-gate if (bk[--cnt] == 0) 6407c478bd9Sstevel@tonic-gate goto null; 6417c478bd9Sstevel@tonic-gate bno--; 6427c478bd9Sstevel@tonic-gate } 6437c478bd9Sstevel@tonic-gate null: 6447c478bd9Sstevel@tonic-gate 6457c478bd9Sstevel@tonic-gate /* 6467c478bd9Sstevel@tonic-gate * Magically calculate the largest valid pointer in the temp file, 6477c478bd9Sstevel@tonic-gate * consing it up from the block number and the count. 6487c478bd9Sstevel@tonic-gate */ 6497c478bd9Sstevel@tonic-gate maxt = ((bno << OFFBTS) | (cnt >> SHFT)) & ~1; 6507c478bd9Sstevel@tonic-gate #ifdef DEBUG 6517c478bd9Sstevel@tonic-gate fprintf(stderr, "bno %d, cnt %d, maxt %o\n", bno, cnt, maxt); 6527c478bd9Sstevel@tonic-gate #endif 6537c478bd9Sstevel@tonic-gate 6547c478bd9Sstevel@tonic-gate /* 6557c478bd9Sstevel@tonic-gate * Now cycle through the line pointers, 6567c478bd9Sstevel@tonic-gate * trashing the Lusers. 6577c478bd9Sstevel@tonic-gate */ 6587c478bd9Sstevel@tonic-gate was = bad = 0; 6597c478bd9Sstevel@tonic-gate for (ip = one; ip <= dol; ip++) 6607c478bd9Sstevel@tonic-gate if (*ip > maxt) { 6617c478bd9Sstevel@tonic-gate #ifdef DEBUG 6627c478bd9Sstevel@tonic-gate fprintf(stderr, "%d bad, %o > %o\n", ip - zero, *ip, maxt); 6637c478bd9Sstevel@tonic-gate #endif 6647c478bd9Sstevel@tonic-gate if (was == 0) 6657c478bd9Sstevel@tonic-gate was = ip - zero; 6667c478bd9Sstevel@tonic-gate *ip = ((HBLKS*BUFSIZE)-8) >> SHFT; 6677c478bd9Sstevel@tonic-gate } else if (was) { 6687c478bd9Sstevel@tonic-gate if (bad == 0) 6697c478bd9Sstevel@tonic-gate fprintf(stderr, gettext(" [Lost line(s):")); 6707c478bd9Sstevel@tonic-gate fprintf(stderr, " %d", was); 6717c478bd9Sstevel@tonic-gate if ((ip - 1) - zero > was) 6727c478bd9Sstevel@tonic-gate fprintf(stderr, "-%d", (ip - 1) - zero); 6737c478bd9Sstevel@tonic-gate bad++; 6747c478bd9Sstevel@tonic-gate was = 0; 6757c478bd9Sstevel@tonic-gate } 6767c478bd9Sstevel@tonic-gate if (was != 0) { 6777c478bd9Sstevel@tonic-gate if (bad == 0) 6787c478bd9Sstevel@tonic-gate fprintf(stderr, " [Lost line(s):"); 6797c478bd9Sstevel@tonic-gate fprintf(stderr, " %d", was); 6807c478bd9Sstevel@tonic-gate if (dol - zero != was) 6817c478bd9Sstevel@tonic-gate fprintf(stderr, "-%d", dol - zero); 6827c478bd9Sstevel@tonic-gate bad++; 6837c478bd9Sstevel@tonic-gate } 6847c478bd9Sstevel@tonic-gate if (bad) 6857c478bd9Sstevel@tonic-gate fprintf(stderr, "]"); 6867c478bd9Sstevel@tonic-gate } 6877c478bd9Sstevel@tonic-gate 6887c478bd9Sstevel@tonic-gate int cntch, cntln, cntodd, cntnull; 6897c478bd9Sstevel@tonic-gate /* 6907c478bd9Sstevel@tonic-gate * Following routines stolen mercilessly from ex. 6917c478bd9Sstevel@tonic-gate */ 692f6db9f27Scf46844 void 693f6db9f27Scf46844 rputfile(void) 6947c478bd9Sstevel@tonic-gate { 6957c478bd9Sstevel@tonic-gate line *a1; 696f6db9f27Scf46844 unsigned char *fp, *lp; 697f6db9f27Scf46844 int nib; 6987c478bd9Sstevel@tonic-gate 6997c478bd9Sstevel@tonic-gate a1 = addr1; 7007c478bd9Sstevel@tonic-gate clrstats(); 7017c478bd9Sstevel@tonic-gate cntln = addr2 - a1 + 1; 7027c478bd9Sstevel@tonic-gate if (cntln == 0) 7037c478bd9Sstevel@tonic-gate return; 7047c478bd9Sstevel@tonic-gate nib = BUFSIZE; 7057c478bd9Sstevel@tonic-gate fp = genbuf; 7067c478bd9Sstevel@tonic-gate do { 7077c478bd9Sstevel@tonic-gate #ifdef DEBUG 7087c478bd9Sstevel@tonic-gate fprintf(stderr,"GETTING A LINE \n"); 7097c478bd9Sstevel@tonic-gate #endif 710*23a1cceaSRoger A. Faulkner getaline(*a1++); 7117c478bd9Sstevel@tonic-gate lp = linebuf; 7127c478bd9Sstevel@tonic-gate #ifdef DEBUG 7137c478bd9Sstevel@tonic-gate fprintf(stderr,"LINE:%s\n",linebuf); 7147c478bd9Sstevel@tonic-gate #endif 7157c478bd9Sstevel@tonic-gate for (;;) { 7167c478bd9Sstevel@tonic-gate if (--nib < 0) { 7177c478bd9Sstevel@tonic-gate nib = fp - genbuf; 7187c478bd9Sstevel@tonic-gate if (write(io, genbuf, nib) != nib) 7197c478bd9Sstevel@tonic-gate wrerror(); 7207c478bd9Sstevel@tonic-gate cntch += nib; 7217c478bd9Sstevel@tonic-gate nib = BUFSIZE; 7227c478bd9Sstevel@tonic-gate fp = genbuf; 7237c478bd9Sstevel@tonic-gate } 7247c478bd9Sstevel@tonic-gate if ((*fp++ = *lp++) == 0) { 7257c478bd9Sstevel@tonic-gate fp[-1] = '\n'; 7267c478bd9Sstevel@tonic-gate break; 7277c478bd9Sstevel@tonic-gate } 7287c478bd9Sstevel@tonic-gate } 7297c478bd9Sstevel@tonic-gate } while (a1 <= addr2); 7307c478bd9Sstevel@tonic-gate nib = fp - genbuf; 7317c478bd9Sstevel@tonic-gate if (write(io, genbuf, nib) != nib) 7327c478bd9Sstevel@tonic-gate wrerror(); 7337c478bd9Sstevel@tonic-gate cntch += nib; 7347c478bd9Sstevel@tonic-gate } 7357c478bd9Sstevel@tonic-gate 736f6db9f27Scf46844 void 737f6db9f27Scf46844 wrerror(void) 7387c478bd9Sstevel@tonic-gate { 7397c478bd9Sstevel@tonic-gate 740f6db9f27Scf46844 rsyserror(); 7417c478bd9Sstevel@tonic-gate } 7427c478bd9Sstevel@tonic-gate 743f6db9f27Scf46844 void 744f6db9f27Scf46844 clrstats(void) 7457c478bd9Sstevel@tonic-gate { 7467c478bd9Sstevel@tonic-gate 7477c478bd9Sstevel@tonic-gate ninbuf = 0; 7487c478bd9Sstevel@tonic-gate cntch = 0; 7497c478bd9Sstevel@tonic-gate cntln = 0; 7507c478bd9Sstevel@tonic-gate cntnull = 0; 7517c478bd9Sstevel@tonic-gate cntodd = 0; 7527c478bd9Sstevel@tonic-gate } 7537c478bd9Sstevel@tonic-gate 7547c478bd9Sstevel@tonic-gate #define READ 0 7557c478bd9Sstevel@tonic-gate #define WRITE 1 7567c478bd9Sstevel@tonic-gate 757f6db9f27Scf46844 void 758*23a1cceaSRoger A. Faulkner getaline(line tl) 7597c478bd9Sstevel@tonic-gate { 760f6db9f27Scf46844 unsigned char *bp, *lp; 761f6db9f27Scf46844 int nl; 7627c478bd9Sstevel@tonic-gate 7637c478bd9Sstevel@tonic-gate lp = linebuf; 7647c478bd9Sstevel@tonic-gate bp = getblock(tl); 7657c478bd9Sstevel@tonic-gate nl = nleft; 7667c478bd9Sstevel@tonic-gate tl &= ~OFFMSK; 7677c478bd9Sstevel@tonic-gate while (*lp++ = *bp++) 7687c478bd9Sstevel@tonic-gate if (--nl == 0) { 7697c478bd9Sstevel@tonic-gate bp = getblock(tl += INCRMT); 7707c478bd9Sstevel@tonic-gate nl = nleft; 7717c478bd9Sstevel@tonic-gate } 7727c478bd9Sstevel@tonic-gate } 7737c478bd9Sstevel@tonic-gate 7747c478bd9Sstevel@tonic-gate int read(); 7757c478bd9Sstevel@tonic-gate int write(); 7767c478bd9Sstevel@tonic-gate 7777c478bd9Sstevel@tonic-gate unsigned char * 7787c478bd9Sstevel@tonic-gate getblock(atl) 7797c478bd9Sstevel@tonic-gate line atl; 7807c478bd9Sstevel@tonic-gate { 781f6db9f27Scf46844 int bno, off; 782f6db9f27Scf46844 unsigned char *p1, *p2; 783f6db9f27Scf46844 int n; 7847c478bd9Sstevel@tonic-gate 7857c478bd9Sstevel@tonic-gate bno = (atl >> OFFBTS) & BLKMSK; 7867c478bd9Sstevel@tonic-gate #ifdef DEBUG 7877c478bd9Sstevel@tonic-gate fprintf(stderr,"GETBLOCK: BLK %d\n",bno); 7887c478bd9Sstevel@tonic-gate #endif 7897c478bd9Sstevel@tonic-gate off = (atl << SHFT) & LBTMSK; 7907c478bd9Sstevel@tonic-gate if (bno >= NMBLKS) 791f6db9f27Scf46844 error((unsigned char *)gettext(" Tmp file too large")); 7927c478bd9Sstevel@tonic-gate nleft = BUFSIZE - off; 7937c478bd9Sstevel@tonic-gate if (bno == iblock) 7947c478bd9Sstevel@tonic-gate return (ibuff + off); 7957c478bd9Sstevel@tonic-gate iblock = bno; 7967c478bd9Sstevel@tonic-gate blkio(bno, ibuff, read); 7977c478bd9Sstevel@tonic-gate if(xtflag) 7987c478bd9Sstevel@tonic-gate if (run_crypt(0L, ibuff, CRSIZE, tperm) == -1) 799f6db9f27Scf46844 rsyserror(); 8007c478bd9Sstevel@tonic-gate #ifdef DEBUG 8017c478bd9Sstevel@tonic-gate fprintf(stderr,"UNENCRYPTED: BLK %d\n",bno); 8027c478bd9Sstevel@tonic-gate #endif 8037c478bd9Sstevel@tonic-gate return (ibuff + off); 8047c478bd9Sstevel@tonic-gate } 8057c478bd9Sstevel@tonic-gate 806f6db9f27Scf46844 void 807f6db9f27Scf46844 blkio(short b, unsigned char *buf, int (*iofcn)()) 8087c478bd9Sstevel@tonic-gate { 8097c478bd9Sstevel@tonic-gate 8107c478bd9Sstevel@tonic-gate int rc; 8117c478bd9Sstevel@tonic-gate lseek(tfile, (long) (unsigned) b * BUFSIZE, 0); 8127c478bd9Sstevel@tonic-gate if ((rc =(*iofcn)(tfile, buf, BUFSIZE)) != BUFSIZE) { 8137c478bd9Sstevel@tonic-gate (void)fprintf(stderr,gettext("Failed on BLK: %d with %d/%d\n"),b,rc,BUFSIZE); 8147c478bd9Sstevel@tonic-gate perror(""); 815f6db9f27Scf46844 rsyserror(); 8167c478bd9Sstevel@tonic-gate } 8177c478bd9Sstevel@tonic-gate } 8187c478bd9Sstevel@tonic-gate 819f6db9f27Scf46844 void 820f6db9f27Scf46844 rsyserror(void) 8217c478bd9Sstevel@tonic-gate { 822ace1a5f1Sdp int save_err = errno; 8237c478bd9Sstevel@tonic-gate 8247c478bd9Sstevel@tonic-gate dirtcnt = 0; 8257c478bd9Sstevel@tonic-gate write(2, " ", 1); 826ace1a5f1Sdp error(strerror(save_err)); 8277c478bd9Sstevel@tonic-gate exit(1); 8287c478bd9Sstevel@tonic-gate } 8297c478bd9Sstevel@tonic-gate 8307c478bd9Sstevel@tonic-gate static int intrupt; 8317c478bd9Sstevel@tonic-gate 832d67944fbSScott Rotondo static void catch(); 833d67944fbSScott Rotondo 8347c478bd9Sstevel@tonic-gate unsigned char * 8357c478bd9Sstevel@tonic-gate mypass(prompt) 8367c478bd9Sstevel@tonic-gate unsigned char *prompt; 8377c478bd9Sstevel@tonic-gate { 8387c478bd9Sstevel@tonic-gate struct termio ttyb; 8397c478bd9Sstevel@tonic-gate unsigned short flags; 840f6db9f27Scf46844 unsigned char *p; 841f6db9f27Scf46844 int c; 8427c478bd9Sstevel@tonic-gate static unsigned char pbuf[9]; 8437c478bd9Sstevel@tonic-gate void (*sig)(); 8447c478bd9Sstevel@tonic-gate 8457c478bd9Sstevel@tonic-gate setbuf(stdin, (char*)NULL); 8467c478bd9Sstevel@tonic-gate sig = signal(SIGINT, catch); 8477c478bd9Sstevel@tonic-gate intrupt = 0; 8487c478bd9Sstevel@tonic-gate (void) ioctl(fileno(stdin), TCGETA, &ttyb); 8497c478bd9Sstevel@tonic-gate flags = ttyb.c_lflag; 8507c478bd9Sstevel@tonic-gate ttyb.c_lflag &= ~(ECHO | ECHOE | ECHOK | ECHONL); 8517c478bd9Sstevel@tonic-gate (void) ioctl(fileno(stdin), TCSETAF, &ttyb); 8527c478bd9Sstevel@tonic-gate (void) fputs((char *)prompt, stderr); 8537c478bd9Sstevel@tonic-gate for(p=pbuf; !intrupt && (c = getc(stdin)) != '\n' && c!= '\r' && c != EOF; ) { 8547c478bd9Sstevel@tonic-gate if(p < &pbuf[8]) 8557c478bd9Sstevel@tonic-gate *p++ = c; 8567c478bd9Sstevel@tonic-gate } 8577c478bd9Sstevel@tonic-gate *p = '\0'; 8587c478bd9Sstevel@tonic-gate (void) putc('\n', stderr); 8597c478bd9Sstevel@tonic-gate ttyb.c_lflag = flags; 8607c478bd9Sstevel@tonic-gate (void) ioctl(fileno(stdin), TCSETA, &ttyb); 8617c478bd9Sstevel@tonic-gate (void) signal(SIGINT, sig); 8627c478bd9Sstevel@tonic-gate if(intrupt) 8637c478bd9Sstevel@tonic-gate (void) kill(getpid(), SIGINT); 8647c478bd9Sstevel@tonic-gate return(pbuf); 8657c478bd9Sstevel@tonic-gate } 8667c478bd9Sstevel@tonic-gate 8677c478bd9Sstevel@tonic-gate static void 8687c478bd9Sstevel@tonic-gate catch() 8697c478bd9Sstevel@tonic-gate { 8707c478bd9Sstevel@tonic-gate ++intrupt; 8717c478bd9Sstevel@tonic-gate } 872