home *** CD-ROM | disk | FTP | other *** search
/ Piper's Pit BBS/FTP: ibm 0010 - 0019 / ibm0010-0019 / ibm0010.tar / ibm0010 / REFLECT.ZIP / UNIXLINK.C < prev    next >
Encoding:
C/C++ Source or Header  |  1989-08-21  |  41.8 KB  |  2,312 lines

  1. #ifndef PART1
  2. #ifndef PART2
  3. #define PART1 1
  4. #define PART2 1
  5. #endif
  6. #endif
  7. #ifdef PART1
  8. #define INIT = {0}
  9. #else
  10. #define INIT
  11. #endif
  12. #ifdef hpux
  13. #define SYSTEM5 1
  14. #endif
  15. #ifdef SYSTEM5
  16. #define TTYSTRUCT termio
  17. #else
  18. #define TTYSTRUCT sgttyb
  19. #endif
  20. #define BYTE unsigned char
  21. #define WORD unsigned short
  22. #define LONG long
  23. #define FAST register
  24. #define VOID int
  25. #define BOOL int
  26. #define YES 1
  27. #define NO 0
  28. #define VERSION "6.01"
  29. #define INIT_TYPE 0
  30. #define START_TYPE 3
  31. #define ASTRT_TYPE 4
  32. #define DATA_TYPE 5
  33. #define EOD_TYPE 6
  34. #define ABORT_TYPE 7
  35. #define AEOD_TYPE 8
  36. #define EXIT_TYPE 9
  37. #define START_LEN 55
  38. #define ASTRT_LEN 90
  39. #define EOD_LEN 2
  40. #define ABORT_LEN 84
  41. #define AEOD_LEN 84
  42. #define EXIT_LEN 2
  43. #define RESIZE_BLK 0
  44. #define DATA_BLK 1
  45. #define DUMMY_BLK 3
  46. #define START_ONLY 1
  47. #define DATA_OR_EOD 2
  48. #define CONTROL_ONLY 3
  49. #define QUIT_NORMAL 0
  50. #define QUIT_SHUTDOWN 1
  51. #define QUIT_READ_TTY 2
  52. #define QUIT_WRITE_TTY 3
  53. #define QUIT_ABORT_TTY 4
  54. #define QUIT_TIMEOUT 5
  55. #define ASCII 'A'
  56. #define FROM_SLAVE 0x00
  57. #define BU_FILENM ".*.*.* /WRQ BACKUP\\ *.*.*."
  58. #define RE_FILENM ".*.*.* /WRQ RESTORE\\ *.*.*."
  59. #define TEMPFILE "r2wrqres.tmp"
  60. #define MAX_SPACES 125
  61. #define REC_SEPARATOR 0xff
  62. #define START 0
  63. #define STABLE 1
  64. #define ESCAPE 2
  65. #define DUPLICATE 3
  66. #define COUNT 4
  67. #define COMPRESS '~'
  68. #define MIN_DUPS 4
  69. #define DATABUFSZ 524
  70. #define UPLDBFSZ 512
  71. #define TT_BUF_OUT 1600
  72. #define IOBUFSZ 512
  73. #define TT_BUF_IN 256
  74. #define TTBUF_MAX 1472
  75. #define VERSZ 8
  76. #define FNAMESZ 42
  77. #define ERRTXSZ 80
  78. #define PATHSIZE 80
  79. #define DEF_BURECSZ 256
  80. #define DEF_BUHASH 128
  81. #define TIME_MIN 10
  82. #define TIME_MAX 20*60
  83. #define NO_TIMEOUT -1
  84. #define TIME_DEFAULT 60
  85. #define DEF_RETRY 5
  86. #define TIMEOUT_EIGHT 20
  87. #ifndef NULL
  88. #define NULL 0
  89. #endif
  90. #ifdef DG
  91. #include <paru.h>
  92. #define SOH 14
  93. int dgcode = 0;
  94. #else
  95. #define SOH 1
  96. #endif
  97. #define STX 2
  98. #define CTRL_C 3
  99. #define CR 13
  100. #define DC1 17
  101. #define XON 17
  102. #define XOFF 19
  103. #define CTRL_Y 25
  104. #define ACK 'S'
  105. #define ACK_T 'T'
  106. #define NAK 'F'
  107. #define NOERROR 0
  108. #define EXISTS 100
  109. #define FILE_NF 52
  110. #define TYPE_CNT 5
  111. #define UPLOAD 0
  112. #define DNLOAD 1
  113. #define BACKUP 2
  114. #define RESTORE 3
  115. #define SAVE 4
  116. #define BU_FNSZ 72
  117. #define BU_MAXRSZ 256
  118. #define BU_VERSZ 4
  119. #define BU_MAXBUCK 1024
  120. #define BU_DEFBUCK 256
  121. #define DUMMY_TIMEOUT 5
  122. #define BU_DIRSZ 97
  123. #define BU_HDRSZ 154
  124. #define CKPT_OKAY 0
  125. #define CKPT_INITIATE 1
  126. #define CKPT_DELETE 2
  127. #define CKPT_INSTALL 3
  128. #define SD_CHAR '\\'
  129. #define AUTOSIZE 300
  130. #define SUBDIR '\001'
  131. #define FCHAR 'C'
  132. #define FDOT 'D'
  133. #define FANY 'A'
  134. #define FSUBDIR 'S'
  135. #define FSUCCEED 'Y'
  136. #define FFAIL 'F'
  137. #include <stdio.h>
  138. #ifdef SYSTEM5
  139. #include <termio.h>
  140. #include <fcntl.h>
  141. #else
  142. #include <sgtty.h>
  143. #endif
  144. #include <signal.h>
  145. #include <sys/types.h>
  146. #include <sys/stat.h>
  147. #include <errno.h>
  148. typedef struct
  149. {
  150. WORD reclen;
  151. LONG filesize;
  152. BYTE method;
  153. BYTE direction;
  154. BYTE filename[42];
  155. BYTE bits_allowed;
  156. BYTE compression;
  157. BYTE option_byte;
  158. } STRTMSG;
  159. typedef struct
  160. {
  161. WORD datalen;
  162. BYTE databuf[DATABUFSZ];
  163. } DATAMSG;
  164. typedef struct {
  165. LONG syn_next;
  166. LONG dfirst;
  167. LONG dlast;
  168. WORD fdate;
  169. WORD ftime;
  170. LONG fsize;
  171. WORD ddate;
  172. WORD dtime;
  173. BYTE dattr;
  174. BYTE fname[BU_FNSZ];
  175. } DIR;
  176. typedef struct {
  177. BYTE version[BU_VERSZ];
  178. WORD recsize;
  179. WORD buckets;
  180. BYTE hrec_count;
  181. WORD hblocking;
  182. LONG free_first;
  183. LONG free_last;
  184. LONG file_last;
  185. WORD bu_date;
  186. WORD bu_time;
  187. BYTE c_status;
  188. BYTE c_dupname;
  189. LONG c_prior;
  190. LONG c_current;
  191. LONG c_bucket;
  192. LONG c_nfirst;
  193. LONG c_newdir;
  194. LONG c_odfirst;
  195. LONG c_odlast;
  196. DIR c_dir;
  197. } HDR;
  198. int tty_timeout();
  199. int send_dummy();
  200. LONG file_size();
  201. BYTE get_raw();
  202. BYTE get_byte();
  203. long get_long();
  204. char *get_string();
  205. BYTE getd_char();
  206. WORD getd_word();
  207. LONG getd_long();
  208. BYTE Bread();
  209. BYTE bgchar();
  210. WORD bgword();
  211. LONG bglink();
  212. LONG bglong();
  213. VOID getd_byte_1();
  214. VOID getd_byte_2();
  215. VOID putd_byte_1();
  216. VOID putd_byte_2();
  217. VOID (*putd_byte)() = putd_byte_1;
  218. VOID (*getd_byte)() = getd_byte_1;
  219. LONG htab[BU_MAXBUCK] INIT;
  220. BYTE bu_rec[BU_MAXRSZ] INIT;
  221. BYTE bu_rec2[BU_MAXRSZ] INIT;
  222. BYTE *bu_ptr INIT;
  223. LONG bu_link INIT;
  224. LONG file_lrec INIT;
  225. LONG backup_eof INIT;
  226. BYTE autotab[AUTOSIZE+1] = {0};
  227. BYTE *autoix = NULL;
  228. DIR dir INIT;
  229. HDR hdr INIT;
  230. BYTE dupname INIT;
  231. LONG prior INIT;
  232. LONG current INIT;
  233. LONG bucket INIT;
  234. LONG nfirst INIT;
  235. LONG newdir INIT;
  236. LONG odfirst INIT;
  237. LONG odlast INIT;
  238. WORD ferrno INIT;
  239. char *ferrtx INIT;
  240. #ifdef PART1
  241. int file_created_yet = NO;
  242. int backup_closed = YES;
  243. int is_lat = NO;
  244. int is_rt = NO;
  245. int _8_bit = NO;
  246. int _7_bit_explicit = NO;
  247. int resized = NO;
  248. int resizing = NO;
  249. int tt_buf_out = TT_BUF_OUT;
  250. char *type[TYPE_CNT] = {"upload", "download", "backup","restore",
  251. "save parameters"};
  252. LONG transfer_type;
  253. int send_dummy_blk = NO;
  254. int buffer_overflow = NO;
  255. unsigned int state = 0;
  256. unsigned char new_putd_chr;
  257. WORD get_crc = 0;
  258. int retry_limit = DEF_RETRY;
  259. int cur_blksz = 116;
  260. WORD data_count = 0;
  261. BYTE pbuf[TT_BUF_OUT] = {NULL};
  262. BYTE *pbufp = (BYTE *) NULL;
  263. WORD pblkno = 1;
  264. WORD put_crc = 0;
  265. BOOL aborting = NO;
  266. BOOL eight_bit = NO;
  267. BOOL soh = SOH;
  268. LONG default_bufsz = TT_BUF_IN;
  269. LONG active_bufsz = TT_BUF_IN;
  270. LONG message_byte_cnt;
  271. BOOL escape_mode = NO;
  272. BOOL b_comp = NO;
  273. LONG sub_block_len = 0;
  274. STRTMSG s_msg = {0};
  275. DATAMSG d_msg = {0};
  276. WORD msg_type = 0;
  277. LONG host_rec_len = 0;
  278. BOOL pc2622 = 0;
  279. BOOL do_readsync = 0;
  280. short image_transfer = NO;
  281. short image_header = YES;
  282. short word_perfect = NO;
  283. BYTE dbuf[DATABUFSZ+4] = {0};
  284. int dbufcnt = 0;
  285. int space_cnt = 0;
  286. BYTE iobuf[IOBUFSZ] = {0};
  287. BYTE op_buf[UPLDBFSZ+1] = {0};
  288. int op_len = 0;
  289. int gbuf_used = 0;
  290. int gbuf_count = 0;
  291. int data_ix = 0;
  292. BOOL eof_data = NO;
  293. int blankct = 0;
  294. BYTE blk_type = 0;
  295. WORD info_len = 0;
  296. WORD in_blkno = 0;
  297. WORD last_blkno = 0;
  298. WORD info_seen = 0;
  299. WORD resize_request = 0;
  300. int errno;
  301. int u_fd = -1;
  302. int u_eof = NO;
  303. int tb_max = 0;
  304. int RF_fd = 0;
  305. int RF_rsize = 0;
  306. int RF_eof = 0;
  307. FILE *RF_ptr;
  308. int timeout = NO_TIMEOUT;
  309. WORD crctab[256] = {
  310. 0,4129,8258,12387,16516,20645,24774,28903,
  311. 33032,37161,41290,45419,49548,53677,57806,61935,
  312. 4657,528,12915,8786,21173,17044,29431,25302,
  313. 37689,33560,45947,41818,54205,50076,62463,58334,
  314. 9314,13379,1056,5121,25830,29895,17572,21637,
  315. 42346,46411,34088,38153,58862,62927,50604,54669,
  316. 13907,9842,5649,1584,30423,26358,22165,18100,
  317. 46939,42874,38681,34616,63455,59390,55197,51132,
  318. 18628,22757,26758,30887,2112,6241,10242,14371,
  319. 51660,55789,59790,63919,35144,39273,43274,47403,
  320. 23285,19156,31415,27286,6769,2640,14899,10770,
  321. 56317,52188,64447,60318,39801,35672,47931,43802,
  322. 27814,31879,19684,23749,11298,15363,3168,7233,
  323. 60846,64911,52716,56781,44330,48395,36200,40265,
  324. 32407,28342,24277,20212,15891,11826,7761,3696,
  325. 65439,61374,57309,53244,48923,44858,40793,36728,
  326. 37256,33193,45514,41451,53516,49453,61774,57711,
  327. 4224,161,12482,8419,20484,16421,28742,24679,
  328. 33721,37784,41979,46042,49981,54044,58239,62302,
  329. 689,4752,8947,13010,16949,21012,25207,29270,
  330. 46570,42443,38312,34185,62830,58703,54572,50445,
  331. 13538,9411,5280,1153,29798,25671,21540,17413,
  332. 42971,47098,34713,38840,59231,63358,50973,55100,
  333. 9939,14066,1681,5808,26199,30326,17941,22068,
  334. 55628,51565,63758,59695,39368,35305,47498,43435,
  335. 22596,18533,30726,26663,6336,2273,14466,10403,
  336. 52093,56156,60223,64286,35833,39896,43963,48026,
  337. 19061,23124,27191,31254,2801,6864,10931,14994,
  338. 64814,60687,56684,52557,48554,44427,40424,36297,
  339. 31782,27655,23652,19525,15522,11395,7392,3265,
  340. 61215,65342,53085,57212,44955,49082,36825,40952,
  341. 28183,32310,20053,24180,11923,16050,3793,7920
  342. };
  343. BYTE gbuf[TTBUF_MAX] = {0};
  344. struct TTYSTRUCT curtty;
  345. struct TTYSTRUCT oldtty;
  346. #define swap(X,Y) {(X)=(X)^(Y); (Y)=(X)^(Y); (X)=(X)^(Y);}
  347. #define docrc(old, c) (old = (old<<8) ^ crctab[((old>>8)^c) & 0xff])
  348. #define LSB(x) ((x) & 0xff)
  349. #define MSB(x) (((x) >> 8) & 0xff)
  350. #define MAX(A,B) ((B>A) ? (B) : (A))
  351. #define WRQRAW (++message_byte_cnt && buffer_overflow ? soh :\
  352. (gbuf_used>=gbuf_count? get_raw(): gbuf[gbuf_used++]))
  353. #define GETC ((data_ix >= d_msg.datalen)? getd_data():\
  354. d_msg.databuf[data_ix++])
  355. #define PUTC(x) {if (dbufcnt>=cur_blksz) putd_flush();\
  356. dbuf[dbufcnt++]=(x);}
  357. #define PUTB(ch) (*pbufp++ = (ch))
  358. #define TREAD(a,b) read(0, a, b)
  359. #define TWRITE(a,b) write(1, a, b)
  360. VOID main(ac, av)
  361. int ac;
  362. char **av;
  363. {
  364. char *ap;
  365. while (ap = *++av)
  366. switch (*ap)
  367. {
  368. case '/':
  369. case '-':
  370. switch (*++ap)
  371. {
  372. case 't':
  373. if (!(*++ap) && !(ap = *++av))
  374. usage();
  375. for (timeout = 0; *ap; ++ap)
  376. if (*ap < '0' || *ap > '9')
  377. usage();
  378. else
  379. timeout = timeout*10 + (*ap - '0');
  380. if (!timeout)
  381. timeout = TIME_MAX;
  382. break;
  383. case 'o':
  384. pc2622 = 1;
  385. break;
  386. #ifdef DG
  387. case 'p':
  388. dgcode = 1;
  389. break;
  390. #endif
  391. default:
  392. usage();
  393. }
  394. break;
  395. default:
  396. usage();
  397. }
  398. tty_open();
  399. if (!_8_bit) {
  400. send_init();
  401. recv_message(START_ONLY);
  402. }
  403. for (;;)
  404. {
  405. if (!strcmp(s_msg.filename, BU_FILENM))
  406. {
  407. transfer_type = BACKUP;
  408. backup();
  409. }
  410. else if (!strcmp(s_msg.filename, RE_FILENM))
  411. {
  412. if (s_msg.direction == FROM_SLAVE)
  413. {
  414. transfer_type = RESTORE;
  415. restore();
  416. }
  417. else
  418. {
  419. transfer_type = SAVE;
  420. save_parms();
  421. }
  422. }
  423. else
  424. {
  425. if (s_msg.direction == FROM_SLAVE)
  426. {
  427. transfer_type = DNLOAD;
  428. dnload();
  429. }
  430. else
  431. {
  432. transfer_type = UPLOAD;
  433. upload();
  434. }
  435. }
  436. recv_message(START_ONLY);
  437. }
  438. }
  439. VOID usage()
  440. {
  441. #ifdef DG
  442. write(2, "usage: dglink [-t timeout_seconds, -o]\n", 40);
  443. #else
  444. write(2, "usage: unixlink [-t timeout_seconds, -o]\n", 40);
  445. #endif
  446. exit(1);
  447. }
  448. VOID dnload()
  449. {
  450. char *addr;
  451. LONG size;
  452. int i, j, k;
  453. if ((size = file_size(s_msg.filename)) == -1) {
  454. send_astrt(FILE_NF, "Requested file not present.", 0L);
  455. }
  456. else if (size == -2)
  457. send_astrt(ferrno, ferrtx, 0L);
  458. else
  459. {
  460. send_astrt(NOERROR, "", size);
  461. {
  462. file_open(s_msg.filename);
  463. data_count = 0;
  464. for (i=file_read(iobuf,IOBUFSZ); i; i=file_read(iobuf,IOBUFSZ))
  465. for (j = 0; j < i; ++j)
  466. { (*putd_byte)(iobuf[j]);
  467. ++data_count;
  468. }
  469. if (b_comp) binary_c_flush();
  470. putd_flush();
  471. file_close();
  472. send_eod();
  473. }
  474. }
  475. }
  476. VOID upload()
  477. {
  478. char *addr;
  479. LONG size;
  480. size = file_size(s_msg.filename);
  481. if (size == -2)  {
  482. send_astrt(ferrno, ferrtx, 0L);
  483. return;
  484. }
  485. if (size == -1)
  486. send_astrt(NOERROR, "", 0L);
  487. else
  488. send_astrt(EXISTS, "File already exists.", size);
  489. getd_init();
  490. op_len = 0;
  491. if (image_transfer == NO) upload_binary_ascii();
  492. else if (image_header == YES) upload_image_head();
  493. else if (word_perfect == YES) upload_image_wp();
  494. else upload_image_nohead();
  495. if (file_close() == -1) send_aeod(ferrno, ferrtx);
  496. else send_aeod(0, "");
  497. }
  498. VOID upload_binary_ascii()
  499. {
  500. LONG i,j;
  501. for (i = (*getd_byte)(); i != EOF; i = (*getd_byte)() ) {
  502. if (op_len >= UPLDBFSZ) {
  503. file_write(op_buf, op_len);
  504. op_len = 0;
  505. }
  506. op_buf[op_len++] = i;
  507. }
  508. if (op_len) file_write(op_buf, op_len);
  509. }
  510. VOID upload_image_nohead()
  511. {
  512. }
  513. VOID upload_image_wp()
  514. {
  515. }
  516. VOID upload_image_head()
  517. {
  518. }
  519. VOID backup()
  520. {
  521. BYTE bu_file[FNAMESZ+1];
  522. WORD new_date, new_time;
  523. int b;
  524. BYTE pname[PATHSIZE+1];
  525. LONG fsize;
  526. WORD fdate, ftime;
  527. BYTE fattr;
  528. LONG i;
  529. LONG backup_desc;
  530. send_astrt(NOERROR, "", 1);
  531. getd_init();
  532. getd_str(bu_file, FNAMESZ);
  533. new_date = getd_word();
  534. new_time = getd_word();
  535. Binit(bu_file, YES, DEF_BURECSZ, DEF_BUHASH);
  536. for (b = (*getd_byte)(); b != EOF; b = (*getd_byte)() )
  537. {
  538. pname[0] = b;
  539. getd_str(&pname[1], PATHSIZE-1);
  540. fsize = getd_long();
  541. fdate = getd_word();
  542. ftime = getd_word();
  543. fattr = getd_char();
  544. Bcreate();
  545. for (i = 0; i < fsize; ++i)
  546. Bwrite(getd_char());
  547. Binstall(new_date, new_time, pname, fsize, fdate, ftime, fattr);
  548. }
  549. if (Bterm() == -1)
  550. send_aeod(ferrno, ferrtx);
  551. else
  552. send_aeod(0, "");
  553. }
  554. VOID save_parms()
  555. {
  556. BYTE s_len;
  557. BYTE bu_file[FNAMESZ+1];
  558. BYTE pname[PATHSIZE+1];
  559. BYTE subdirs[2];
  560. getd_init();
  561. file_create(TEMPFILE);
  562. send_astrt(NOERROR, "", 1);
  563. getd_str(bu_file, FNAMESZ);
  564. getd_str(pname, PATHSIZE);
  565. getd_str(subdirs, 2);
  566. s_len = strlen(bu_file) + 32;
  567. file_write(&s_len, 1);
  568. file_write(bu_file, s_len-32);
  569. s_len = strlen(pname) + 32;
  570. file_write(&s_len, 1);
  571. file_write(pname, s_len-32);
  572. if (subdirs[0] == 'S')
  573. file_write("S\n", 2);
  574. else
  575. file_write("N\n", 2);
  576. for (;;) {
  577. getd_pname(pname,PATHSIZE);
  578. s_len = strlen(pname);
  579. if (!(s_len))
  580. break;
  581. s_len += 32;
  582. file_write(&s_len,1);
  583. file_write(pname, s_len-32);
  584. file_write("\n", 1);
  585. }
  586. if (file_close() == -1)
  587. send_aeod(ferrno, ferrtx);
  588. else
  589. send_aeod(0, "");
  590. }
  591. VOID restore()
  592. {
  593. LONG i;
  594. BYTE bu_file[FNAMESZ+1];
  595. BYTE pname[PATHSIZE+1];
  596. BYTE subdir;
  597. BOOL subs_ok;
  598. BOOL more;
  599. BYTE s_len;
  600. int temp_fd, rest_fd;
  601. file_open(TEMPFILE);
  602. temp_fd = u_fd;
  603. if (file_read(&s_len, 1) != 1)
  604. shutdown(-16, "Invalid temp file - restore");
  605. if (s_len -= 32)
  606. if (file_read(bu_file, s_len) != s_len)
  607. shutdown(-17, "Invalid temp file - restore");
  608. bu_file[s_len] = NULL;
  609. if (file_read(&s_len, 1) != 1)
  610. shutdown(-18, "Invalid temp file - restore");
  611. if (s_len -= 32)
  612. if (file_read(pname, s_len) != s_len)
  613. shutdown(-19, "Invalid temp file - restore");
  614. pname[s_len] = NULL;
  615. if (file_read(&subdir, 1) != 1)
  616. shutdown(-20, "Invalid temp file - restore");
  617. if (subdir == 'S')
  618. subs_ok = YES;
  619. else
  620. subs_ok = NO;
  621. if (!Binit(bu_file, NO)) {
  622. send_astrt(FILE_NF, "Requested backup file not present.");
  623. }
  624. else if (!pname[0]) {
  625. send_astrt(-21, "Invalid pathname to be restored.");
  626. }
  627. else {
  628. send_astrt(NOERROR, "", 1);
  629. for (;;) {
  630. for (more = Bopenf(pname, subs_ok); more; more = Bopenn()) {
  631. putd_str(dir.fname);
  632. putd_long(dir.fsize);
  633. putd_word(dir.ddate);
  634. putd_word(dir.dtime);
  635. (*putd_byte)(dir.dattr);
  636. for (i = 0; i < dir.fsize; ++i)
  637. (*putd_byte)(Bread());
  638. }
  639. for (i=0; i <= AUTOSIZE; i++)
  640. autotab[AUTOSIZE+1] = 0;
  641. autoix = NULL;
  642. rest_fd = u_fd;
  643. u_fd = temp_fd;
  644. file_read(&s_len,1);
  645. if ((file_read(&s_len, 1) == 1) &&
  646. (file_read(pname, s_len-32) == s_len-32)) {
  647. pname[s_len-32] = NULL;
  648. u_fd = rest_fd;
  649. }
  650. else {
  651. file_close();
  652. file_delete(TEMPFILE);
  653. u_fd = rest_fd;
  654. break;
  655. }
  656. }
  657. if (b_comp) binary_c_flush();
  658. putd_flush();
  659. Bterm();
  660. send_eod();
  661. }
  662. }
  663. VOID shutdown(errcode, errtext)
  664. WORD errcode;
  665. BYTE *errtext;
  666. {
  667. static BOOL allover = NO;
  668. if (!allover)
  669. {
  670. allover = YES;
  671. send_abort(errcode, errtext);
  672. recv_message(CONTROL_ONLY);
  673. }
  674. quit(QUIT_SHUTDOWN);
  675. }
  676. VOID quit(i)
  677. {
  678. tty_close();
  679. exit(i);
  680. }
  681. BYTE get_raw()
  682. {
  683. while (gbuf_used >= gbuf_count) {
  684. gbuf_count = tty_read(gbuf);
  685. gbuf_used = 0;
  686. }
  687. return(gbuf[gbuf_used++]);
  688. }
  689. remove_pad(n)
  690. int n;
  691. {
  692. }
  693. BYTE get_byte()
  694. {
  695. BYTE c;
  696. if (!(_8_bit)) {
  697. if ((c = WRQRAW) == '&') {
  698. if (((c = WRQRAW) == '#') && (c = WRQRAW) != '#' && c != '&') c ^= 0x40;
  699. c ^= 0xC0;
  700. }
  701. else if (c == '#' && (c = WRQRAW) != '#' && c != '&') c ^= 0x40;
  702. }
  703. else c = WRQRAW;
  704. docrc(get_crc, c);
  705. return(c);
  706. }
  707. WORD get_word()
  708. {
  709. BYTE c;
  710. c = get_byte();
  711. return((c << 8) + get_byte());
  712. }
  713. LONG get_long()
  714. {
  715. WORD w;
  716. w = get_word();
  717. return((((LONG) w) << 16) + get_word());
  718. }
  719. int get_buffer(buf, cnt)
  720. BYTE *buf;
  721. int cnt;
  722. {
  723. for (;!buffer_overflow && cnt; ++buf, --cnt) *buf = get_byte();
  724. }
  725. VOID getd_init()
  726. {
  727. data_ix = 0;
  728. d_msg.datalen = 0;
  729. eof_data = NO;
  730. blankct = 0;
  731. }
  732. int getd_byte_1()
  733. {
  734. BYTE c;
  735. int i;
  736. get_loop:
  737. if (blankct)
  738. {
  739. --blankct;
  740. return (' ');
  741. }
  742. if (data_ix >= d_msg.datalen)
  743. {
  744. data_ix = 0;
  745. recv_message(DATA_OR_EOD);
  746. if (msg_type == EOD_TYPE)
  747. {
  748. d_msg.datalen = 0;
  749. eof_data = YES;
  750. }
  751. }
  752. if (eof_data)
  753. return (EOF);
  754. c = d_msg.databuf[data_ix++];
  755. if (s_msg.method == ASCII)
  756. {
  757. if (c == REC_SEPARATOR)
  758. {
  759. return('\n');
  760. }
  761. else
  762. {
  763. if (escape_mode)
  764. {
  765. escape_mode = NO;
  766. c = c | 0x80;
  767. goto take_char;
  768. }
  769. if (c == 254)
  770. if (eight_bit)
  771. {
  772. escape_mode = YES;
  773. goto get_loop;
  774. }
  775. if (c & 0x80)
  776. {
  777. blankct = c & 0x7F;
  778. return ((*getd_byte)());
  779. }
  780. }
  781. }
  782. take_char:
  783. i = c;
  784. return(i & 0x00FF);
  785. }
  786. int getd_byte_2()
  787. {
  788. static unsigned char dup,
  789. count;
  790. static unsigned int state = STABLE;
  791. int c;
  792. for (;;) {
  793. switch (state) {
  794. case STABLE: if ((c = GETC) != COMPRESS)
  795. return(c);
  796. state = DUPLICATE;
  797. count = GETC - 32;
  798. dup = GETC;
  799. return(dup);
  800. case DUPLICATE: if (--count)
  801. return(dup);
  802. state = STABLE;
  803. }
  804. }
  805. }
  806. int getd_data()
  807. {
  808. data_ix = 0;
  809. recv_message(DATA_OR_EOD);
  810. if (msg_type == EOD_TYPE)
  811. return(EOF);
  812. else return(d_msg.databuf[data_ix++]);
  813. }
  814. BYTE getd_char()
  815. {
  816. int c;
  817. if ((c = (*getd_byte)()) == EOF)
  818. shutdown(-37, "File hasn't changed since last backup");
  819. return(c & 0xFF);
  820. }
  821. WORD getd_word()
  822. {
  823. BYTE c;
  824. c = getd_char();
  825. return( (c<<8) + ((*getd_byte)() & 0xFF) );
  826. }
  827. LONG getd_long()
  828. {
  829. WORD w;
  830. w = getd_word();
  831. return( (((LONG) w) << 16) + (getd_word() & 0xFFFF) );
  832. }
  833. VOID getd_str(buf, maxsz)
  834. BYTE *buf;
  835. int maxsz;
  836. {
  837. while(*buf++ = getd_char())
  838. if (!(maxsz--))
  839. shutdown(-23, "Internal error - string too long.");
  840. }
  841. VOID getd_pname(buf, maxsz)
  842. BYTE *buf;
  843. int maxsz;
  844. {
  845. int c;
  846. for (;;) {
  847. c = (*getd_byte)();
  848. if (c == EOF || c == 0) {
  849. *buf++ = (BYTE) 0;
  850. return;
  851. }
  852. *buf++ = (BYTE) c;
  853. if (!(maxsz--))
  854. shutdown(-23, "Internal error - string too long.");
  855. }
  856. }
  857. VOID put_byte(c)
  858. BYTE c;
  859. {
  860. c &= 0xff;
  861. docrc(put_crc, c);
  862. if (!(_8_bit)) {
  863. if ((c == '#') || (c == '&')) PUTB('#');
  864. else if ((c == 0x7F) || (c < 0x20)) {
  865. PUTB('#');
  866. c ^= 0x40;
  867. }
  868. else if (c > 0x7F) {
  869. PUTB('&');
  870. c ^= 0xC0;
  871. if ((c == '#') || (c == '&')) PUTB('#');
  872. else if ((c == 0x7F) || (c < 0x20)) {
  873. PUTB('#');
  874. c ^= 0x40;
  875. }
  876. }
  877. }
  878. PUTB(c);
  879. if (pbufp >= pbuf + tt_buf_out)
  880. shutdown(-9, "Internal buffer overflow.");
  881. }
  882. VOID put_word(w)
  883. WORD w;
  884. {
  885. put_byte(MSB(w));
  886. put_byte(LSB(w));
  887. }
  888. VOID put_long(lo)
  889. LONG lo;
  890. {
  891. put_word((lo>>16) & 0xFFFF);
  892. put_word(lo & 0xFFFF);
  893. }
  894. VOID put_string(p, maxlen)
  895. BYTE *p;
  896. int maxlen;
  897. {
  898. for (; (maxlen > 1) && *p; --maxlen)
  899. put_byte(*p++);
  900. while (maxlen-- > 1)
  901. put_byte(NULL);
  902. put_byte(NULL);
  903. }
  904. VOID put_begin(msgtype, infolen)
  905. WORD msgtype;
  906. int infolen;
  907. {
  908. pbuf[0] = soh;
  909. pbufp = pbuf + 1;
  910. put_crc = 0;
  911. put_byte(DATA_BLK);
  912. put_word(infolen);
  913. put_word(pblkno);
  914. put_word(msgtype);
  915. aborting = (msgtype == ABORT_TYPE) ? YES : NO;
  916. }
  917. put_end()
  918. {
  919. int i;
  920. static char c[TTBUF_MAX];
  921. put_word(put_crc);
  922. if (!(++pblkno & 0xffff)) pblkno = 1;
  923. for(;;) {
  924. tty_write(pbuf,pbufp - pbuf);
  925. i = tty_read(c);
  926. if (c[--i]==ACK)
  927. return(YES);
  928. else if (c[i] == ACK_T) {
  929. if (!aborting) {
  930. recv_message(CONTROL_ONLY);
  931. }
  932. return(YES);
  933. }
  934. }
  935. }
  936. VOID putd_byte_1(c)
  937. BYTE c;
  938. {
  939. if (space_cnt)
  940. if (c == ' ')
  941. {
  942. if (++space_cnt > MAX_SPACES)
  943. dbuf[dbufcnt-1] = MAX_SPACES | 0x80;
  944. else
  945. return;
  946. }
  947. else
  948. {
  949. if (space_cnt > 1)
  950. dbuf[dbufcnt-1] = space_cnt | 0x80;
  951. space_cnt = 0;
  952. }
  953. if (dbufcnt >= cur_blksz)
  954. putd_flush();
  955. if (s_msg.method == ASCII)
  956. {
  957. if (c & 0x80)
  958. {
  959. if (eight_bit)
  960. {
  961. dbuf[dbufcnt++] = 0xFE;
  962. if (dbufcnt >= cur_blksz)
  963. putd_flush();
  964. c = (c & 0x7F);
  965. dbuf[dbufcnt++] = c;
  966. return;
  967. }
  968. c = (c & 0x7F);
  969. }
  970. if (c == ' ')
  971. space_cnt = 1;
  972. else if (c == '\n')
  973. {
  974. c = REC_SEPARATOR;
  975. }
  976. }
  977. dbuf[dbufcnt++] = c;
  978. }
  979. VOID putd_byte_2(c)
  980. unsigned char c;
  981. {
  982. static unsigned char old,
  983. rep,
  984. count;
  985. do {
  986. switch (state)
  987. {
  988. case START: old = c;
  989. state = STABLE;
  990. break;
  991. case STABLE: new_putd_chr = c;
  992. if (new_putd_chr == old) {
  993. state = DUPLICATE;
  994. count = 1;
  995. break;
  996. }
  997. swap(old,new_putd_chr);
  998. if (new_putd_chr == COMPRESS) {
  999. count = 1;
  1000. rep = new_putd_chr;
  1001. state = COUNT;
  1002. }
  1003. PUTC(new_putd_chr);
  1004. break;
  1005. case ESCAPE: rep = new_putd_chr;
  1006. new_putd_chr = COMPRESS;
  1007. state = COUNT;
  1008. PUTC(new_putd_chr);
  1009. break;
  1010. case DUPLICATE: new_putd_chr = c;
  1011. ++count;
  1012. if (count && old == new_putd_chr)
  1013. break;
  1014. swap(old,new_putd_chr);
  1015. if (count >= MIN_DUPS || !count ||
  1016. new_putd_chr == COMPRESS) {
  1017. state = ESCAPE;
  1018. break;
  1019. }
  1020. --count;
  1021. while (count < MIN_DUPS) {
  1022. PUTC(new_putd_chr);
  1023. --count;
  1024. }
  1025. state = STABLE;
  1026. break;
  1027. case COUNT: PUTC(count+32);
  1028. state = STABLE;
  1029. PUTC(rep);
  1030. break;
  1031. }
  1032. }
  1033. while (state == ESCAPE || state == COUNT);
  1034. }
  1035. VOID binary_c_flush()
  1036. {
  1037. putd_byte_2(~new_putd_chr);
  1038. state = START;
  1039. }
  1040. VOID putd_word(w)
  1041. WORD w;
  1042. {
  1043. (*putd_byte)((BYTE) (MSB(w)));
  1044. (*putd_byte)((BYTE) (LSB(w)));
  1045. }
  1046. VOID putd_long(lo)
  1047. LONG lo;
  1048. {
  1049. putd_word( (WORD) ((lo>>16) & 0xFFFF) );
  1050. putd_word( (WORD) (lo & 0xFFFF) );
  1051. }
  1052. VOID putd_str(s)
  1053. BYTE *s;
  1054. {
  1055. while (*s)
  1056. (*putd_byte)(*s++);
  1057. (*putd_byte)(NULL);
  1058. }
  1059. VOID putd_flush()
  1060. {
  1061. if (space_cnt)
  1062. {
  1063. dbuf[dbufcnt-1] = space_cnt | 0x80;
  1064. space_cnt = 0;
  1065. }
  1066. send_data(dbuf, dbufcnt);
  1067. dbufcnt = 0;
  1068. }
  1069. VOID recv_message(expected)
  1070. {
  1071. for (;;)
  1072. {
  1073. recv_block();
  1074. if (blk_type == DATA_BLK && msg_type == EXIT_TYPE)
  1075. quit(QUIT_NORMAL);
  1076. if (in_blkno && (in_blkno == last_blkno))
  1077. continue;
  1078. if (!in_blkno)
  1079. last_blkno = 0;
  1080. else if (!(++last_blkno & 0xffff))
  1081. last_blkno = 1;
  1082. if (last_blkno != in_blkno)
  1083. shutdown(-5, "Block number sequence error.");
  1084. if (blk_type != RESIZE_BLK && blk_type != DATA_BLK
  1085. && blk_type != DUMMY_BLK)
  1086. shutdown(-1, "Bad block type.");
  1087. if (expected == CONTROL_ONLY)
  1088. {
  1089. if (blk_type != DUMMY_BLK && blk_type != RESIZE_BLK)
  1090. shutdown(-2, "Unexpected message type.");
  1091. return;
  1092. }
  1093. if (blk_type == DATA_BLK)
  1094. {
  1095. if (expected == START_ONLY && msg_type != START_TYPE)
  1096. shutdown(-3, "Unexpected message type.");
  1097. if (expected == DATA_OR_EOD
  1098. && (msg_type != DATA_TYPE && msg_type != EOD_TYPE))
  1099. shutdown(-4, "Unexpected message type.");
  1100. return;
  1101. }
  1102. }
  1103. }
  1104. VOID recv_block()
  1105. {
  1106. for (;;) {
  1107. while (WRQRAW != soh)
  1108. ;
  1109. message_byte_cnt = 1;
  1110. get_crc = 0;
  1111. blk_type = get_byte();
  1112. if ((info_len = get_word()) & 1) ++info_len;
  1113. in_blkno = get_word();
  1114. if (info_len <= DATABUFSZ) {
  1115. info_seen = 0;
  1116. if (recv_fields()) {
  1117. for (; info_seen < info_len; ++info_seen) get_byte();
  1118. get_word();
  1119. if (!get_crc) {
  1120. ack_it(YES);
  1121. if (blk_type == RESIZE_BLK)
  1122. cur_blksz = resize_request - 12;
  1123. return;
  1124. }
  1125. }
  1126. }
  1127. nak_it();
  1128. }
  1129. }
  1130. BOOL recv_fields()
  1131. {
  1132. if (blk_type == RESIZE_BLK)
  1133. {
  1134. if ((resize_request = get_word()) > DATABUFSZ)
  1135. resize_request = 128;
  1136. info_seen = 2;
  1137. }
  1138. else if (blk_type == DATA_BLK)
  1139. {
  1140. if (info_len < 2)
  1141. return(NO);
  1142. msg_type = get_word();
  1143. info_seen = 2;
  1144. if (msg_type == START_TYPE)
  1145. {
  1146. if (info_len < 52)
  1147. return(NO);
  1148. s_msg.reclen = get_word();
  1149. s_msg.filesize = get_long();
  1150. s_msg.method = get_byte();
  1151. s_msg.direction = get_byte();
  1152. get_buffer(s_msg.filename, 42);
  1153. if (info_len > 52)
  1154. {
  1155. s_msg.bits_allowed = get_byte();
  1156. if (s_msg.bits_allowed = '8')
  1157. eight_bit = YES;
  1158. s_msg.compression = get_byte();
  1159. if (s_msg.compression = 'c' && s_msg.method != ASCII) {
  1160. b_comp = YES;
  1161. putd_byte = putd_byte_2;
  1162. getd_byte = getd_byte_2;
  1163. }
  1164. info_seen = 54;
  1165. }
  1166. else info_seen = 52;
  1167. }
  1168. else if (msg_type == DATA_TYPE)
  1169. {
  1170. if (info_len < 4)
  1171. return(NO);
  1172. if ((d_msg.datalen = get_word()) > DATABUFSZ)
  1173. return(NO);
  1174. if (gbuf_count>sub_block_len)
  1175. sub_block_len = gbuf_count;
  1176. get_buffer(d_msg.databuf, d_msg.datalen);
  1177. info_seen = d_msg.datalen + 4;
  1178. }
  1179. }
  1180. return(YES);
  1181. }
  1182. VOID ack_it(do_dc1)
  1183. int do_dc1;
  1184. {
  1185. tty_write("S", 1);
  1186. }
  1187. VOID ackt_it(do_dc1)
  1188. int do_dc1;
  1189. {
  1190. tty_write("T", 1);
  1191. }
  1192. VOID nak_it()
  1193. {
  1194. tty_write("F", 1);
  1195. }
  1196. VOID send_init()
  1197. {
  1198. int j,k;
  1199. j = 0;
  1200. do {
  1201. put_begin(INIT_TYPE, 14);
  1202. put_string("1.20", 5);
  1203. put_byte('6');
  1204. put_byte('.');
  1205. put_byte('0');
  1206. put_byte('1');
  1207. put_byte('8');
  1208. put_byte('c');
  1209. put_byte(0x00);
  1210. } while (!(k=put_end()) && ++j<retry_limit && --pblkno);
  1211. }
  1212. VOID send_astrt(errcode, errtext, filesz)
  1213. WORD errcode;
  1214. BYTE *errtext;
  1215. LONG filesz;
  1216. {
  1217. int j,k;
  1218. j = 0;
  1219. do {
  1220. put_begin(ASTRT_TYPE, ASTRT_LEN);
  1221. put_word(errcode);
  1222. put_string(errtext, ERRTXSZ);
  1223. put_word(1);
  1224. put_long(filesz);
  1225. } while (!(k=put_end()) && ++j<retry_limit && --pblkno);
  1226. }
  1227. VOID send_data(data, datalen)
  1228. BYTE *data;
  1229. WORD datalen;
  1230. {
  1231. BYTE *g;
  1232. WORD h;
  1233. int i,j,k;
  1234. i = datalen & 1;
  1235. j = 0;
  1236. do {
  1237. h = datalen;
  1238. g = data;
  1239. put_begin(DATA_TYPE, h + 4);
  1240. put_word(data_count);
  1241. while (h--) put_byte(*g++);
  1242. if (i) put_byte(NULL);
  1243. } while (!(k=put_end()) && ++j < retry_limit && --pblkno);
  1244. data_count = 0;
  1245. }
  1246. VOID send_eod()
  1247. {
  1248. int j,k;
  1249. j = 0;
  1250. do {
  1251. put_begin(EOD_TYPE, EOD_LEN);
  1252. } while (!(k=put_end()) && ++j<retry_limit && --pblkno);
  1253. }
  1254. VOID send_abort(errcode, errtext)
  1255. WORD errcode;
  1256. BYTE *errtext;
  1257. {
  1258. int j,k;
  1259. do {
  1260. put_begin(ABORT_TYPE, ABORT_LEN);
  1261. put_word(errcode);
  1262. put_string(errtext, ERRTXSZ);
  1263. } while (!(k=put_end()) && ++j<retry_limit && --pblkno);
  1264. }
  1265. VOID send_aeod(errcode, errtext)
  1266. WORD errcode;
  1267. BYTE *errtext;
  1268. {
  1269. int j,k;
  1270. j = 0;
  1271. do {
  1272. put_begin(AEOD_TYPE, AEOD_LEN);
  1273. put_word(errcode);
  1274. put_string(errtext, ERRTXSZ);
  1275. } while (!(k=put_end()) && ++j<retry_limit && --pblkno);
  1276. }
  1277. VOID send_resize(size)
  1278. int size;
  1279. {
  1280. }
  1281. VOID tty_open()
  1282. {
  1283. VOID tty_abort(), tty_timeout();
  1284. #ifdef SYSTEM5
  1285. ioctl(0, TCGETA, &oldtty);
  1286. curtty = oldtty;
  1287. curtty.c_lflag &= ~ECHO;
  1288. curtty.c_cc[2] = 8;
  1289. curtty.c_cc[3] = 21;
  1290. ioctl(0, TCSETA, &curtty);
  1291. #else
  1292. gtty(0, &oldtty);
  1293. curtty = oldtty;
  1294. curtty.sg_flags &= ~ECHO;
  1295. stty(0, &curtty);
  1296. #endif
  1297. signal(SIGHUP, tty_abort);
  1298. signal(SIGINT, tty_abort);
  1299. signal(SIGQUIT, tty_abort);
  1300. if (timeout != NO_TIMEOUT)
  1301. {
  1302. alarm(0);
  1303. signal(SIGALRM, tty_timeout);
  1304. }
  1305. tty_flush();
  1306. }
  1307. VOID tty_close()
  1308. {
  1309. #ifdef SYSTEM5
  1310. ioctl(0, TCSETA, &oldtty);
  1311. #else
  1312. stty(0, &oldtty);
  1313. #endif
  1314. }
  1315. int tty_read(buf)
  1316. char *buf;
  1317. {
  1318. tb_max = 0;
  1319. while (!tb_max)
  1320. {
  1321. if (timeout != NO_TIMEOUT)
  1322. alarm(timeout);
  1323. if ((tb_max = TREAD(buf, default_bufsz)) < 1)
  1324. quit(QUIT_READ_TTY);
  1325. while (tb_max && (buf[tb_max-1] == '\n' || buf[tb_max-1] == '\r'))
  1326. --tb_max;
  1327. }
  1328. return(tb_max);
  1329. }
  1330. VOID tty_write(buf, blen)
  1331. char *buf;
  1332. int blen;
  1333. {
  1334. char xbuf[2];
  1335. #ifdef DG
  1336. fflush(stdout);
  1337. #endif
  1338. if (blen > 1 && TWRITE(buf, blen-1) < 1)
  1339. quit(QUIT_WRITE_TTY);
  1340. if (blen)
  1341. {
  1342. xbuf[0] = buf[blen-1];
  1343. if (!pc2622)
  1344. {
  1345. xbuf[1] = '\r';
  1346. if (TWRITE(xbuf, 2) < 1)
  1347. quit(QUIT_WRITE_TTY);
  1348. }
  1349. }
  1350. else
  1351. {
  1352. if (!pc2622)
  1353. {
  1354. if (TWRITE("\r", 1) < 1)
  1355. quit(QUIT_WRITE_TTY);
  1356. }
  1357. }
  1358. }
  1359. VOID tty_flush()
  1360. {
  1361. #ifdef SYSTEM5
  1362. ioctl(0, TCSETA, &curtty);
  1363. #else
  1364. stty(0, &curtty);
  1365. #endif
  1366. }
  1367. VOID tty_timeout()
  1368. {
  1369. quit(QUIT_TIMEOUT);
  1370. }
  1371. VOID tty_abort()
  1372. {
  1373. quit(QUIT_ABORT_TTY);
  1374. }
  1375. VOID file_open(fn)
  1376. char *fn;
  1377. {
  1378. u_eof = NO;
  1379. u_fd = fl_open(fn, 0);
  1380. }
  1381. VOID file_create(fn)
  1382. char *fn;
  1383. {
  1384. u_fd = fl_create(fn);
  1385. }
  1386. int file_read(buf, blen)
  1387. char *buf;
  1388. int blen;
  1389. {
  1390. int i;
  1391. if (u_eof)
  1392. return(0);
  1393. if ((i = fl_read(u_fd, buf, blen)) != blen)
  1394. u_eof = YES;
  1395. return(i);
  1396. }
  1397. VOID file_write(buf, blen)
  1398. char *buf;
  1399. int blen;
  1400. {
  1401. if (file_created_yet == NO && transfer_type == UPLOAD) {
  1402. file_create(s_msg.filename);
  1403. file_created_yet = YES;
  1404. }
  1405. fl_write(u_fd, buf, blen);
  1406. }
  1407. int file_close()
  1408. {
  1409. return(fl_close(u_fd));
  1410. }
  1411. long file_size(fn)
  1412. char *fn;
  1413. {
  1414. struct stat sbuf;
  1415. if (stat(fn, &sbuf) == -1)
  1416. {
  1417. ferrno = errno;
  1418. ferrtx = "stat() failed";
  1419. #ifdef ENOTDIR
  1420. if (errno == ENOTDIR)
  1421. ferrtx = "a component of the path prefix is not a directory.";
  1422. #endif
  1423. #ifdef ENOENT
  1424. if (errno == ENOENT)
  1425. return(-1L);
  1426. #endif
  1427. #ifdef EACCES
  1428. if (errno == EACCES)
  1429. ferrtx = "read permission is denied for the specified file.";
  1430. #endif
  1431. return(-2L);
  1432. }
  1433. return(sbuf.st_size);
  1434. }
  1435. VOID file_delete(nm)
  1436. char *nm;
  1437. {
  1438. if (unlink(nm))
  1439. shutdown(errno, "error on file delete.");
  1440. }
  1441. VOID RF_create(nm, rsize)
  1442. char *nm;
  1443. int rsize;
  1444. {
  1445. if (fl_close(fl_create(nm)) == -1)
  1446. shutdown(ferrno, "close after RF_create failed.");
  1447. RF_open(nm, rsize);
  1448. }
  1449. VOID RF_open(nm, rsize)
  1450. char *nm;
  1451. int rsize;
  1452. {
  1453. RF_rsize = rsize;
  1454. RF_fd = fl_open(nm, 2);
  1455. }
  1456. VOID RF_read(buf, rnum)
  1457. char *buf;
  1458. LONG rnum;
  1459. {
  1460. RF_position(rnum);
  1461. if (fl_read(RF_fd, buf, RF_rsize) != RF_rsize)
  1462. shutdown(-45, "Invalid backup file record.");
  1463. }
  1464. VOID RF_write(buf, rnum)
  1465. char *buf;
  1466. LONG rnum;
  1467. {
  1468. RF_position(rnum);
  1469. fl_write(RF_fd, buf, RF_rsize);
  1470. }
  1471. int RF_close()
  1472. {
  1473. return(fl_close(RF_fd));
  1474. }
  1475. VOID RF_position(rnum)
  1476. LONG rnum;
  1477. {
  1478. long rval;
  1479. long lseek();
  1480. if ((rval = lseek(RF_fd, rnum * RF_rsize, 0)) == -1L)
  1481. {
  1482. ferrno = errno;
  1483. ferrtx = "lseek failed.";
  1484. #ifdef EBADF
  1485. if (errno == EBADF)
  1486. ferrtx = "lseek: invalid file handle.";
  1487. #endif
  1488. #ifdef EINVAL
  1489. if (errno == EINVAL)
  1490. ferrtx = "lseek: invalid origin or offset.";
  1491. #endif
  1492. shutdown(ferrno, ferrtx);
  1493. }
  1494. }
  1495. int fl_open(fn, open_flag)
  1496. char *fn;
  1497. int open_flag;
  1498. {
  1499. int r_value;
  1500. #ifdef SYSTEM5
  1501. if (open_flag == 0)
  1502. open_flag = O_RDONLY;
  1503. else
  1504. open_flag = O_RDWR;
  1505. #endif
  1506. if ((r_value = open(fn, open_flag)) == -1)
  1507. {
  1508. ferrno = errno;
  1509. ferrtx = "open failed; file not found or inaccessible.";
  1510. #ifdef ENOTDIR
  1511. if (errno == ENOTDIR)
  1512. ferrtx = "a component of the path prefix is not a directory.";
  1513. #endif
  1514. #ifdef ENOENT
  1515. if (errno == ENOENT)
  1516. ferrtx = "the specified file does not exist.";
  1517. #endif
  1518. #ifdef EACCES
  1519. if (errno == EACCES)
  1520. ferrtx = "read permission is denied for the specified file.";
  1521. #endif
  1522. shutdown(ferrno, ferrtx);
  1523. }
  1524. return(r_value);
  1525. }
  1526. int fl_create(fn)
  1527. char *fn;
  1528. {
  1529. int r_value;
  1530. #ifdef DG
  1531. if (dgcode)
  1532. r_value = dg_creat(fn, 0666, $FPRV);
  1533. else
  1534. r_value = dg_creat(fn, 0666, $FTXT);
  1535. if (r_value == -1)
  1536. #else
  1537. if ((r_value = creat(fn, 0666)) == -1)
  1538. #endif
  1539. {
  1540. ferrno = errno;
  1541. ferrtx = "open failed; file not creatable.";
  1542. #ifdef ENOTDIR
  1543. if (errno == ENOTDIR)
  1544. ferrtx = "a component of the path prefix is not a directory.";
  1545. #endif
  1546. #ifdef ENOENT
  1547. if (errno == ENOENT)
  1548. ferrtx = "a component of the path prefix does not exist.";
  1549. #endif
  1550. #ifdef EACCES
  1551. if (errno == EACCES)
  1552. ferrtx = "search/write permission denied for the specified file.";
  1553. #endif
  1554. #ifdef EISDIR
  1555. if (errno == EISDIR)
  1556. ferrtx = "specified file is a directory.";
  1557. #endif
  1558. #ifdef EROFS
  1559. if (errno == EROFS)
  1560. ferrtx = "file would reside on a read-only file system.";
  1561. #endif
  1562. shutdown(ferrno, ferrtx);
  1563. }
  1564. return(r_value);
  1565. }
  1566. int fl_close(fd)
  1567. int fd;
  1568. {
  1569. if (close(fd) == -1)
  1570. {
  1571. ferrno = errno;
  1572. ferrtx = "close failed.";
  1573. #ifdef EBADF
  1574. if (errno == EBADF)
  1575. ferrtx = "close: bad file handle.";
  1576. #endif
  1577. return(-1);
  1578. }
  1579. else
  1580. return(0);
  1581. }
  1582. int fl_read(fd, buf, blen)
  1583. int fd;
  1584. char *buf;
  1585. int blen;
  1586. {
  1587. int i, progress;
  1588. progress = 0;
  1589. for (i = 1; (i >= 1) && blen; buf += i, blen -= i, progress += i)
  1590. i = read(fd, buf, blen);
  1591. if (i == -1)
  1592. shutdown(errno, "read failed.");
  1593. return(progress);
  1594. }
  1595. VOID fl_write(fd, buf, blen)
  1596. int fd;
  1597. char *buf;
  1598. int blen;
  1599. {
  1600. int i;
  1601. if ((i = write(fd, buf, blen)) == -1)
  1602. {
  1603. ferrno = errno;
  1604. ferrtx = "write failed.";
  1605. #ifdef EFBIG
  1606. if (errno == EFBIG)
  1607. ferrtx = "file size exceeds maximum allowed.";
  1608. #endif
  1609. shutdown(ferrno, ferrtx);
  1610. }
  1611. if (i != blen)
  1612. shutdown(EINVAL, "write: out of room.");
  1613. }
  1614. #endif
  1615. #ifdef PART2
  1616. BOOL Binit(fname, create_it, rec_size, ibuckets)
  1617. char *fname;
  1618. BOOL create_it;
  1619. int rec_size, ibuckets;
  1620. {
  1621. int i;
  1622. if (file_size(fname) < BU_HDRSZ)
  1623. {
  1624. if (!create_it)
  1625. return(NO);
  1626. else
  1627. {
  1628. if (ibuckets == 0)
  1629. ibuckets = BU_DEFBUCK;
  1630. if (ibuckets > BU_MAXBUCK)
  1631. ibuckets = BU_MAXBUCK;
  1632. if (rec_size > BU_MAXRSZ)
  1633. rec_size = BU_MAXRSZ;
  1634. if (rec_size < BU_HDRSZ)
  1635. rec_size = BU_HDRSZ;
  1636. if (rec_size < BU_DIRSZ)
  1637. rec_size = BU_DIRSZ;
  1638. RF_create(fname, rec_size);
  1639. hdr.version[0] = '1';
  1640. hdr.version[1] = '.';
  1641. hdr.version[2] = '0';
  1642. hdr.version[3] = '0';
  1643. hdr.recsize = rec_size;
  1644. hdr.buckets = ibuckets;
  1645. hdr.hblocking = hdr.recsize >> 2;
  1646. hdr.hrec_count = hdr.buckets / hdr.hblocking;
  1647. if (hdr.buckets % hdr.hblocking)
  1648. ++hdr.hrec_count;
  1649. hdr.free_first = 0L;
  1650. hdr.free_last = 0L;
  1651. hdr.file_last = hdr.hrec_count;
  1652. hdr.bu_date = 0;
  1653. hdr.bu_time = 0;
  1654. checkpoint(CKPT_INITIATE);
  1655. crit_initiate();
  1656. return(YES);
  1657. }
  1658. }
  1659. file_open(fname);
  1660. file_read(bu_rec, BU_HDRSZ);
  1661. hdr_read();
  1662. if (file_close() == -1)
  1663. shutdown(ferrno, ferrtx);
  1664. RF_open(fname, hdr.recsize);
  1665. if (hdr.c_status != CKPT_INITIATE)
  1666. for (i = 1; i <= hdr.hrec_count; ++i)
  1667. hash_read((LONG) i);
  1668. if (hdr.c_status != CKPT_OKAY)
  1669. {
  1670. info_restore();
  1671. switch (hdr.c_status)
  1672. {
  1673. case CKPT_INITIATE:
  1674. crit_initiate();
  1675. break;
  1676. case CKPT_DELETE:
  1677. crit_delete();
  1678. break;
  1679. case CKPT_INSTALL:
  1680. crit_install();
  1681. break;
  1682. default:
  1683. shutdown(-99, "Invalid ckeckpoint status");
  1684. }
  1685. }
  1686. return(YES);
  1687. }
  1688. VOID crit_initiate()
  1689. {
  1690. int i;
  1691. for (i = 0; i < hdr.buckets; ++i)
  1692. htab[i] = 0;
  1693. for (i = 1; i <= hdr.hrec_count; ++i)
  1694. hash_write((LONG) i);
  1695. checkpoint(CKPT_OKAY);
  1696. }
  1697. int Bterm()
  1698. {
  1699. hdr_write();
  1700. return(RF_close());
  1701. }
  1702. VOID Bcreate()
  1703. {
  1704. nfirst = 0L;
  1705. file_lrec = hdr.file_last;
  1706. bu_link = hdr.free_first;
  1707. bplink(0L);
  1708. }
  1709. VOID Bdelete(pathname)
  1710. BYTE *pathname;
  1711. {
  1712. if (!Blookup(pathname))
  1713. return;
  1714. checkpoint(CKPT_DELETE);
  1715. crit_delete();
  1716. }
  1717. VOID crit_delete()
  1718. {
  1719. Add_to_free(dir.dfirst, dir.dlast);
  1720. Set_prior(dir.syn_next);
  1721. Add_to_free(current, current);
  1722. checkpoint(CKPT_OKAY);
  1723. }
  1724. VOID Binstall(new_date, new_time, pathname, size, date, time, attr)
  1725. WORD new_date, new_time;
  1726. BYTE *pathname;
  1727. LONG size;
  1728. WORD date, time;
  1729. BYTE attr;
  1730. {
  1731. FAST BYTE *p, *q;
  1732. int i;
  1733. LONG first_drec = 0L, last_drec = 0L;
  1734. if (size > 0)
  1735. {
  1736. last_drec = bu_link;
  1737. data_write(YES);
  1738. if (hdr.free_first > 0L)
  1739. first_drec = hdr.free_first;
  1740. else
  1741. first_drec = hdr.file_last + 1;
  1742. if (nfirst > 0L)
  1743. last_drec = file_lrec;
  1744. }
  1745. hdr.free_first = bu_link;
  1746. dupname = Blookup(pathname);
  1747. odfirst = dir.dfirst;
  1748. odlast = dir.dlast;
  1749. dir.dfirst = first_drec;
  1750. dir.dlast = last_drec;
  1751. dir.fdate = new_date;
  1752. dir.ftime = new_time;
  1753. dir.fsize = size;
  1754. dir.dtime = time;
  1755. dir.ddate = date;
  1756. dir.dattr = attr;
  1757. p = dir.fname;
  1758. q = pathname;
  1759. for (i = 0; i < BU_FNSZ && *q; ++i)
  1760. *p++ = *q++;
  1761. for (; i < BU_FNSZ; ++i)
  1762. *p++ = NULL;
  1763. hdr.bu_date = new_date;
  1764. hdr.bu_time = new_time;
  1765. hdr.file_last = file_lrec;
  1766. if (!dupname)
  1767. {
  1768. if (hdr.free_first == 0L)
  1769. newdir = ++hdr.file_last;
  1770. else
  1771. {
  1772. newdir = hdr.free_first;
  1773. RF_read(bu_rec, hdr.free_first);
  1774. hdr.free_first = bglink();
  1775. }
  1776. }
  1777. checkpoint(CKPT_INSTALL);
  1778. crit_install();
  1779. }
  1780. VOID crit_install()
  1781. {
  1782. if (nfirst == 0L && dir.fsize > 0L
  1783. && hdr.free_last != dir.dlast)
  1784. {
  1785. RF_read(bu_rec, dir.dlast);
  1786. bplink(0L);
  1787. RF_write(bu_rec, dir.dlast);
  1788. }
  1789. if (nfirst > 0L && hdr.free_last > 0L)
  1790. {
  1791. RF_read(bu_rec, hdr.free_last);
  1792. bplink(nfirst);
  1793. RF_write(bu_rec, hdr.free_last);
  1794. }
  1795. if (hdr.free_first == 0L)
  1796. hdr.free_last = 0L;
  1797. if (dupname)
  1798. Add_to_free(odfirst, odlast);
  1799. else
  1800. {
  1801. Set_prior(newdir);
  1802. dir.syn_next = current;
  1803. current = newdir;
  1804. }
  1805. dir_write(current);
  1806. checkpoint(CKPT_OKAY);
  1807. }
  1808. BOOL Bopenf(path, subdirs_ok)
  1809. char *path;
  1810. BOOL subdirs_ok;
  1811. {
  1812. if (Bcompile(path, subdirs_ok))
  1813. {
  1814. if (!Bposition((WORD) 0, YES))
  1815. return(NO);
  1816. while (!Bmatch(dir.fname)) {
  1817. if (!Badvance(YES))
  1818. return(NO);
  1819. }
  1820. return(YES);
  1821. }
  1822. else
  1823. return(Blookup(path));
  1824. }
  1825. BOOL Bopenn()
  1826. {
  1827. while (Badvance(YES))
  1828. {
  1829. if (Bmatch(dir.fname))
  1830. return(YES);
  1831. }
  1832. return(NO);
  1833. }
  1834. BYTE Bread()
  1835. {
  1836. return(bgchar());
  1837. }
  1838. VOID Bwrite(c)
  1839. {
  1840. bpchar(c);
  1841. }
  1842. BOOL Badvance(keep_going)
  1843. BOOL keep_going;
  1844. {
  1845. prior = current;
  1846. current = dir.syn_next;
  1847. if (current > 0L)
  1848. {
  1849. dir_read(current);
  1850. return(YES);
  1851. }
  1852. if (!keep_going)
  1853. return(NO);
  1854. return(Bposition((WORD) bucket+1, YES));
  1855. }
  1856. WORD Bhash(name)
  1857. char *name;
  1858. {
  1859. WORD hash_value;
  1860. int i;
  1861. hash_value = 0;
  1862. while (*name)
  1863. hash_value += *name++;
  1864. return(hash_value % hdr.buckets);
  1865. }
  1866. BOOL Blookup(name)
  1867. char *name;
  1868. {
  1869. int rval;
  1870. if (!Bposition(Bhash(name), NO))
  1871. return(NO);
  1872. while ((rval = strncmp(name, dir.fname, BU_FNSZ)) > 0)
  1873. {
  1874. if (!Badvance(NO))
  1875. return(NO);
  1876. }
  1877. return(rval == 0);
  1878. }
  1879. BOOL Bposition(hash_value, keep_going)
  1880. WORD hash_value;
  1881. BOOL keep_going;
  1882. {
  1883. prior = 0;
  1884. current = 0;
  1885. for (bucket = hash_value; bucket < hdr.buckets; ++bucket)
  1886. {
  1887. current = htab[bucket];
  1888. if (current > 0L)
  1889. {
  1890. dir_read(current);
  1891. return(YES);
  1892. }
  1893. if (!keep_going)
  1894. return(NO);
  1895. }
  1896. return(NO);
  1897. }
  1898. VOID Add_to_free(first, last)
  1899. LONG first, last;
  1900. {
  1901. if (first == 0L)
  1902. return;
  1903. if (hdr.free_first == 0L && first != last)
  1904. {
  1905. hdr.free_first = first;
  1906. hdr.free_last = last;
  1907. }
  1908. else
  1909. {
  1910. bplink(hdr.free_first);
  1911. RF_write(bu_rec, last);
  1912. hdr.free_first = first;
  1913. if (hdr.free_last == 0L)
  1914. hdr.free_last = last;
  1915. }
  1916. }
  1917. VOID data_write(eof_flag)
  1918. BOOL eof_flag;
  1919. {
  1920. int i;
  1921. bpfill();
  1922. if (bu_link == 0L)
  1923. {
  1924. ++file_lrec;
  1925. if (eof_flag)
  1926. bplink(0L);
  1927. else
  1928. bplink(file_lrec + 1L);
  1929. RF_write(bu_rec, file_lrec);
  1930. if (nfirst == 0L)
  1931. nfirst = file_lrec;
  1932. }
  1933. else
  1934. {
  1935. RF_read(bu_rec2, bu_link);
  1936. for (i = 0; i < 4; ++i)
  1937. bu_rec[i] = bu_rec2[i];
  1938. RF_write(bu_rec, bu_link);
  1939. bu_link = bglink();
  1940. }
  1941. bplink(0L);
  1942. }
  1943. VOID Set_prior(link_value)
  1944. LONG link_value;
  1945. {
  1946. if (prior == 0L)
  1947. {
  1948. htab[bucket] = link_value;
  1949. hash_write( (LONG) ((bucket / hdr.hblocking) + 1));
  1950. }
  1951. else
  1952. {
  1953. RF_read(bu_rec, prior);
  1954. bplink(link_value);
  1955. RF_write(bu_rec, prior);
  1956. }
  1957. }
  1958. static add_chr(c)
  1959. BYTE c;
  1960. {
  1961. if (autoix >= autotab + AUTOSIZE)
  1962. shutdown(-35, "Internal error.");
  1963. *autoix++ = c;
  1964. }
  1965. BOOL Bcompile(pname, subs_ok)
  1966. FAST BYTE *pname;
  1967. BOOL subs_ok;
  1968. {
  1969. FAST BYTE *p, *q, *r;
  1970. int i;
  1971. BOOL wild = NO;
  1972. BYTE buf[PATHSIZE+2];
  1973. if ((i = strlen(pname)) > PATHSIZE || i < 1)
  1974. shutdown(-46, "Internal error.");
  1975. if (subs_ok)
  1976. {
  1977. for (p = q = pname; *p; ++p)
  1978. if (*p == SD_CHAR)
  1979. q = p + 1;
  1980. for (p = buf; pname < q;)
  1981. *p++ = *pname++;
  1982. *p++ = SUBDIR;
  1983. while (*p++ = *pname++)
  1984. ;
  1985. pname = buf;
  1986. }
  1987. for (autoix = autotab; *pname; ++pname)
  1988. switch (*pname)
  1989. {
  1990. case '*':
  1991. for (i = 0; i < 8; ++i)
  1992. add_chr(FANY);
  1993. while (*pname != '.' && *pname != SD_CHAR && *pname)
  1994. ++pname;
  1995. --pname;
  1996. wild = YES;
  1997. break;
  1998. case '?':
  1999. add_chr(FANY);
  2000. wild = YES;
  2001. break;
  2002. case SUBDIR:
  2003. add_chr(FSUBDIR);
  2004. wild = YES;
  2005. break;
  2006. case '.':
  2007. add_chr(FDOT);
  2008. break;
  2009. default:
  2010. add_chr(FCHAR);
  2011. add_chr(*pname);
  2012. }
  2013. if (wild)
  2014. {
  2015. add_chr(FCHAR);
  2016. add_chr(NULL);
  2017. add_chr(FSUCCEED);
  2018. return(YES);
  2019. }
  2020. else
  2021. {
  2022. autoix = autotab;
  2023. add_chr(FFAIL);
  2024. return(NO);
  2025. }
  2026. }
  2027. BOOL Bmatch(s)
  2028. FAST BYTE *s;
  2029. {
  2030. FAST BYTE *p, *q;
  2031. for (p = autotab; ;)
  2032. switch (*p++)
  2033. {
  2034. case FCHAR:
  2035. if (*p++ != *s++)
  2036. return(NO);
  2037. break;
  2038. case FDOT:
  2039. if (*s == '.')
  2040. ++s;
  2041. else if (*s)
  2042. return(NO);
  2043. break;
  2044. case FSUBDIR:
  2045. for (q = s; *q; ++q)
  2046. if (*q == SD_CHAR)
  2047. s = q + 1;
  2048. break;
  2049. case FANY:
  2050. if (*s == SD_CHAR)
  2051. return(NO);
  2052. if (*s && *s != '.')
  2053. ++s;
  2054. break;
  2055. case FSUCCEED:
  2056. return(YES);
  2057. default:
  2058. return(NO);
  2059. }
  2060. }
  2061. BYTE bgchar()
  2062. {
  2063. if ((bu_ptr - bu_rec) >= hdr.recsize)
  2064. {
  2065. RF_read(bu_rec, bu_link);
  2066. bu_link = bglink();
  2067. }
  2068. return(*bu_ptr++);
  2069. }
  2070. VOID bgstr(s, c)
  2071. BYTE *s;
  2072. int c;
  2073. {
  2074. while (c--)
  2075. *s++ = bgchar();
  2076. }
  2077. WORD bgword()
  2078. {
  2079. BYTE c;
  2080. c = bgchar();
  2081. return( (c<<8) + (bgchar() & 0xff));
  2082. }
  2083. LONG bglong()
  2084. {
  2085. WORD w;
  2086. w = bgword();
  2087. return( (((LONG) w) << 16) + (bgword() & 0xffff));
  2088. }
  2089. LONG bglink()
  2090. {
  2091. bu_ptr = bu_rec;
  2092. return(bglong());
  2093. }
  2094. VOID bpchar(c)
  2095. BYTE c;
  2096. {
  2097. if ((bu_ptr - bu_rec) >= hdr.recsize)
  2098. data_write(NO);
  2099. *bu_ptr++ = c;
  2100. }
  2101. VOID bpstr(s, c)
  2102. BYTE *s;
  2103. int c;
  2104. {
  2105. while (c--)
  2106. bpchar(*s++);
  2107. }
  2108. VOID bpword(w)
  2109. WORD w;
  2110. {
  2111. bpchar( (BYTE) (w>>8));
  2112. bpchar( (BYTE) w);
  2113. }
  2114. VOID bplong(l)
  2115. LONG l;
  2116. {
  2117. bpword( (WORD) (l>>16));
  2118. bpword( (WORD) l);
  2119. }
  2120. VOID bplink(l)
  2121. LONG l;
  2122. {
  2123. bu_ptr = bu_rec;
  2124. bplong(l);
  2125. }
  2126. VOID bpfill()
  2127. {
  2128. while ((bu_ptr - bu_rec) < hdr.recsize)
  2129. bpchar(NULL);
  2130. }
  2131. VOID hdr_read()
  2132. {
  2133. bu_ptr = bu_rec;
  2134. hdr.recsize = BU_HDRSZ;
  2135. bgstr(hdr.version, BU_VERSZ);
  2136. hdr.recsize = bgword();
  2137. hdr.buckets = bgword();
  2138. hdr.hrec_count = bgchar();
  2139. hdr.hblocking = bgword();
  2140. hdr.free_first = bglong();
  2141. hdr.free_last = bglong();
  2142. hdr.file_last = bglong();
  2143. hdr.bu_date = bgword();
  2144. hdr.bu_time = bgword();
  2145. hdr.c_status = bgchar();
  2146. hdr.c_dupname = bgchar();
  2147. hdr.c_prior = bglong();
  2148. hdr.c_current = bglong();
  2149. hdr.c_bucket = bglong();
  2150. hdr.c_nfirst = bglong();
  2151. hdr.c_newdir = bglong();
  2152. hdr.c_odfirst = bglong();
  2153. hdr.c_odlast = bglong();
  2154. hdr.c_dir.syn_next = bglong();
  2155. hdr.c_dir.dfirst = bglong();
  2156. hdr.c_dir.dlast = bglong();
  2157. hdr.c_dir.fdate = bgword();
  2158. hdr.c_dir.ftime = bgword();
  2159. hdr.c_dir.fsize = bglong();
  2160. hdr.c_dir.ddate = bgword();
  2161. hdr.c_dir.dtime = bgword();
  2162. hdr.c_dir.dattr = bgchar();
  2163. bgstr(hdr.c_dir.fname, BU_FNSZ);
  2164. }
  2165. VOID hdr_write()
  2166. {
  2167. bu_ptr = bu_rec;
  2168. bpstr(hdr.version, BU_VERSZ);
  2169. bpword(hdr.recsize);
  2170. bpword(hdr.buckets);
  2171. bpchar(hdr.hrec_count);
  2172. bpword(hdr.hblocking);
  2173. bplong(hdr.free_first);
  2174. bplong(hdr.free_last);
  2175. bplong(hdr.file_last);
  2176. bpword(hdr.bu_date);
  2177. bpword(hdr.bu_time);
  2178. bpchar(hdr.c_status);
  2179. bpchar(hdr.c_dupname);
  2180. bplong(hdr.c_prior);
  2181. bplong(hdr.c_current);
  2182. bplong(hdr.c_bucket);
  2183. bplong(hdr.c_nfirst);
  2184. bplong(hdr.c_newdir);
  2185. bplong(hdr.c_odfirst);
  2186. bplong(hdr.c_odlast);
  2187. bplong(hdr.c_dir.syn_next);
  2188. bplong(hdr.c_dir.dfirst);
  2189. bplong(hdr.c_dir.dlast);
  2190. bpword(hdr.c_dir.fdate);
  2191. bpword(hdr.c_dir.ftime);
  2192. bplong(hdr.c_dir.fsize);
  2193. bpword(hdr.c_dir.ddate);
  2194. bpword(hdr.c_dir.dtime);
  2195. bpchar(hdr.c_dir.dattr);
  2196. bpstr(hdr.c_dir.fname, BU_FNSZ);
  2197. bpfill();
  2198. RF_write(bu_rec, 0L);
  2199. }
  2200. VOID checkpoint(st)
  2201. BYTE st;
  2202. {
  2203. FAST BYTE *p, *q;
  2204. FAST int i;
  2205. hdr.c_status = st;
  2206. hdr.c_dupname = dupname;
  2207. hdr.c_prior = prior;
  2208. hdr.c_current = current;
  2209. hdr.c_bucket = bucket;
  2210. hdr.c_nfirst = nfirst;
  2211. hdr.c_newdir = newdir;
  2212. hdr.c_odfirst = odfirst;
  2213. hdr.c_odlast = odlast;
  2214. hdr.c_dir.syn_next = dir.syn_next;
  2215. hdr.c_dir.dfirst = dir.dfirst;
  2216. hdr.c_dir.dlast = dir.dlast;
  2217. hdr.c_dir.fdate = dir.fdate;
  2218. hdr.c_dir.ftime = dir.ftime;
  2219. hdr.c_dir.fsize = dir.fsize;
  2220. hdr.c_dir.ddate = dir.ddate;
  2221. hdr.c_dir.dtime = dir.dtime;
  2222. hdr.c_dir.dattr = dir.dattr;
  2223. p = hdr.c_dir.fname;
  2224. q = dir.fname;
  2225. for (i = 0; i < BU_FNSZ; ++i)
  2226. *p++ = *q++;
  2227. hdr_write();
  2228. }
  2229. VOID info_restore()
  2230. {
  2231. FAST BYTE *p, *q;
  2232. FAST int i;
  2233. dupname = hdr.c_dupname;
  2234. prior = hdr.c_prior;
  2235. current = hdr.c_current;
  2236. bucket = hdr.c_bucket;
  2237. nfirst = hdr.c_nfirst;
  2238. newdir = hdr.c_newdir;
  2239. odfirst = hdr.c_odfirst;
  2240. odlast = hdr.c_odlast;
  2241. dir.syn_next = hdr.c_dir.syn_next;
  2242. dir.dfirst = hdr.c_dir.dfirst;
  2243. dir.dlast = hdr.c_dir.dlast;
  2244. dir.fdate = hdr.c_dir.fdate;
  2245. dir.ftime = hdr.c_dir.ftime;
  2246. dir.fsize = hdr.c_dir.fsize;
  2247. dir.ddate = hdr.c_dir.ddate;
  2248. dir.dtime = hdr.c_dir.dtime;
  2249. dir.dattr = hdr.c_dir.dattr;
  2250. p = dir.fname;
  2251. q = hdr.c_dir.fname;
  2252. for (i = 0; i < BU_FNSZ; ++i)
  2253. *p++ = *q++;
  2254. }
  2255. VOID hash_read(r)
  2256. LONG r;
  2257. {
  2258. FAST int offset, i;
  2259. RF_read(bu_rec, r);
  2260. offset = (r-1) * hdr.hblocking;
  2261. bu_ptr = bu_rec;
  2262. for (i = 0; i < hdr.hblocking; ++i)
  2263. if (offset < hdr.buckets)
  2264. htab[offset++] = bglong();
  2265. }
  2266. VOID hash_write(r)
  2267. LONG r;
  2268. {
  2269. FAST int offset, i;
  2270. offset = (r-1) * hdr.hblocking;
  2271. bu_ptr = bu_rec;
  2272. for (i = 0; i < hdr.hblocking; ++i)
  2273. if (offset < hdr.buckets)
  2274. bplong(htab[offset++]);
  2275. bpfill();
  2276. RF_write(bu_rec, r);
  2277. }
  2278. VOID dir_read(r)
  2279. LONG r;
  2280. {
  2281. RF_read(bu_rec, r);
  2282. dir.syn_next = bglink();
  2283. dir.dfirst = bglong();
  2284. dir.dlast = bglong();
  2285. dir.fdate = bgword();
  2286. dir.ftime = bgword();
  2287. dir.fsize = bglong();
  2288. dir.ddate = bgword();
  2289. dir.dtime = bgword();
  2290. dir.dattr = bgchar();
  2291. bgstr(dir.fname, BU_FNSZ);
  2292. bu_ptr = bu_rec + hdr.recsize + 1;
  2293. bu_link = dir.dfirst;
  2294. }
  2295. VOID dir_write(r)
  2296. LONG r;
  2297. {
  2298. bplink(dir.syn_next);
  2299. bplong(dir.dfirst);
  2300. bplong(dir.dlast);
  2301. bpword(dir.fdate);
  2302. bpword(dir.ftime);
  2303. bplong(dir.fsize);
  2304. bpword(dir.ddate);
  2305. bpword(dir.dtime);
  2306. bpchar(dir.dattr);
  2307. bpstr(dir.fname, BU_FNSZ);
  2308. bpfill();
  2309. RF_write(bu_rec, r);
  2310. }
  2311. #endif PART2
  2312.