1/* $NetBSD: supmsg.c,v 1.17 2009/10/17 22:26:13 christos Exp $ */ 2 3/* 4 * Copyright (c) 1992 Carnegie Mellon University 5 * All Rights Reserved. 6 * 7 * Permission to use, copy, modify and distribute this software and its 8 * documentation is hereby granted, provided that both the copyright 9 * notice and this permission notice appear in all copies of the 10 * software, derivative works or modified versions, and any portions 11 * thereof, and that both notices appear in supporting documentation. 12 * 13 * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" 14 * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR 15 * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. 16 * 17 * Carnegie Mellon requests users of this software to return to 18 * 19 * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU 20 * School of Computer Science 21 * Carnegie Mellon University 22 * Pittsburgh PA 15213-3890 23 * 24 * any improvements or extensions that they make and grant Carnegie Mellon 25 * the rights to redistribute these changes. 26 */ 27/* 28 ********************************************************************** 29 * HISTORY 30 * 31 * 7-July-93 Nate Williams at Montana State University 32 * Modified SUP to use gzip based compression when sending files 33 * across the network to save BandWidth 34 * 35 * Revision 2.4 92/09/09 22:05:17 mrt 36 * Moved PFI definition under __STDC__ conditional since it 37 * is already defined in libc.h in this case. 38 * [92/09/01 mrt] 39 * 40 * Revision 2.3 92/08/11 12:08:12 mrt 41 * Added copyright 42 * [92/08/10 mrt] 43 * Brad's changes: Delinted, Incorporated updated variable 44 * argument list usage from old msgxfer.c 45 * [92/07/24 mrt] 46 * 47 * Revision 2.2 89/08/23 15:02:56 gm0w 48 * Created from separate message modules. 49 * [89/08/14 gm0w] 50 * 51 ********************************************************************** 52 */ 53#include <stdio.h> 54#include <sys/types.h> 55#include <sys/stat.h> 56#include "libc.h" 57#include "c.h" 58#include "supcdefs.h" 59#include "supextern.h" 60#define MSGSUBR 61#define MSGFILE 62#include "supmsg.h" 63 64/* 65 * signon message 66 */ 67extern int pgmver; /* program version of partner */ 68extern int pgmversion; /* my program version */ 69extern char *scmver; /* scm version of partner */ 70extern int fspid; /* process id of fileserver */ 71 72static int refuseone(TREE *, void *); 73static int listone(TREE *, void *); 74static int needone(TREE *, void *); 75static int denyone(TREE *, void *); 76static int writeone(TREE *, void *); 77 78int 79msgsignon(void) 80{ 81 int x; 82 83 if (isserver) { 84 x = readmsg(MSGSIGNON); 85 if (x == SCMOK) 86 x = readint(&protver); 87 if (x == SCMOK) 88 x = readint(&pgmver); 89 if (x == SCMOK) 90 x = readstring(&scmver); 91 if (x == SCMOK) 92 x = readmend(); 93 } else { 94 x = writemsg(MSGSIGNON); 95 if (x == SCMOK) 96 x = writeint(PROTOVERSION); 97 if (x == SCMOK) 98 x = writeint(pgmversion); 99 if (x == SCMOK) 100 x = writestring(scmversion); 101 if (x == SCMOK) 102 x = writemend(); 103 } 104 return (x); 105} 106 107int 108msgsignonack(void) 109{ 110 int x; 111 112 if (isserver) { 113 x = writemsg(MSGSIGNONACK); 114 if (x == SCMOK) 115 x = writeint(PROTOVERSION); 116 if (x == SCMOK) 117 x = writeint(pgmversion); 118 if (x == SCMOK) 119 x = writestring(scmversion); 120 if (x == SCMOK) 121 x = writeint(fspid); 122 if (x == SCMOK) 123 x = writemend(); 124 } else { 125 x = readmsg(MSGSIGNONACK); 126 if (x == SCMOK) 127 x = readint(&protver); 128 if (x == SCMOK) 129 x = readint(&pgmver); 130 if (x == SCMOK) 131 x = readstring(&scmver); 132 if (x == SCMOK) 133 x = readint(&fspid); 134 if (x == SCMOK) 135 x = readmend(); 136 } 137 return (x); 138} 139/* 140 * setup message 141 */ 142extern int xpatch; /* setup crosspatch to a new client */ 143extern char *xuser; /* user,group,acct for crosspatch */ 144extern char *collname; /* base directory */ 145extern char *basedir; /* base directory */ 146extern int basedev; /* base directory device */ 147extern int baseino; /* base directory inode */ 148extern time_t lasttime; /* time of last upgrade */ 149extern int listonly; /* only listing files, no data xfer */ 150extern int newonly; /* only send new files */ 151extern char *release; /* release name */ 152extern int setupack; /* ack return value for setup */ 153 154int 155msgsetup(void) 156{ 157 int x; 158 159 if (isserver) { 160 x = readmsg(MSGSETUP); 161 if (x != SCMOK) 162 return (x); 163 if (protver >= 7) { 164 x = readint(&xpatch); 165 if (x != SCMOK) 166 return (x); 167 } else 168 xpatch = FALSE; 169 if (xpatch) { 170 x = readstring(&xuser); 171 if (x != SCMOK) 172 return (x); 173 return (readmend()); 174 } 175 x = readstring(&collname); 176 if (x == SCMOK) 177 x = readint((void *) &lasttime); 178 if (x == SCMOK) 179 x = readstring(&basedir); 180 if (x == SCMOK) 181 x = readint(&basedev); 182 if (x == SCMOK) 183 x = readint(&baseino); 184 if (x == SCMOK) 185 x = readint(&listonly); 186 if (x == SCMOK) 187 x = readint(&newonly); 188 if (x == SCMOK) { 189 if (protver < 6) 190 release = NULL; 191 else 192 x = readstring(&release); 193 } 194 if (x == SCMOK) 195 x = readmend(); 196 } else { 197 x = writemsg(MSGSETUP); 198 if (x != SCMOK) 199 return (x); 200 if (protver >= 7) { 201 x = writeint(xpatch); 202 if (x != SCMOK) 203 return (x); 204 } 205 if (xpatch) { 206 x = writestring(xuser); 207 if (x != SCMOK) 208 return (x); 209 return (writemend()); 210 } 211 if (x == SCMOK) 212 x = writestring(collname); 213 if (x == SCMOK) 214 x = writeint((int) lasttime); 215 if (x == SCMOK) 216 x = writestring(basedir); 217 if (x == SCMOK) 218 x = writeint(basedev); 219 if (x == SCMOK) 220 x = writeint(baseino); 221 if (x == SCMOK) 222 x = writeint(listonly); 223 if (x == SCMOK) 224 x = writeint(newonly); 225 if (x == SCMOK && protver >= 6) 226 x = writestring(release); 227 if (x == SCMOK) 228 x = writemend(); 229 } 230 return (x); 231} 232 233int 234msgsetupack(void) 235{ 236 if (isserver) 237 return (writemint(MSGSETUPACK, setupack)); 238 return (readmint(MSGSETUPACK, &setupack)); 239} 240/* 241 * crypt test message 242 */ 243extern char *crypttest; /* encryption test string */ 244 245int 246msgcrypt(void) 247{ 248 if (isserver) 249 return (readmstr(MSGCRYPT, &crypttest)); 250 return (writemstr(MSGCRYPT, crypttest)); 251} 252 253int 254msgcryptok(void) 255{ 256 if (isserver) 257 return (writemnull(MSGCRYPTOK)); 258 return (readmnull(MSGCRYPTOK)); 259} 260/* 261 * login message 262 */ 263extern char *logcrypt; /* login encryption test */ 264extern char *loguser; /* login username */ 265extern char *logpswd; /* password for login */ 266extern int logack; /* login ack status */ 267extern char *logerror; /* error from login */ 268 269int 270msglogin(void) 271{ 272 int x; 273 if (isserver) { 274 x = readmsg(MSGLOGIN); 275 if (x == SCMOK) 276 x = readstring(&logcrypt); 277 if (x == SCMOK) 278 x = readstring(&loguser); 279 if (x == SCMOK) 280 x = readstring(&logpswd); 281 if (x == SCMOK) 282 x = readmend(); 283 } else { 284 x = writemsg(MSGLOGIN); 285 if (x == SCMOK) 286 x = writestring(logcrypt); 287 if (x == SCMOK) 288 x = writestring(loguser); 289 if (x == SCMOK) 290 x = writestring(logpswd); 291 if (x == SCMOK) 292 x = writemend(); 293 } 294 return (x); 295} 296 297int 298msglogack(void) 299{ 300 int x; 301 if (isserver) { 302 x = writemsg(MSGLOGACK); 303 if (x == SCMOK) 304 x = writeint(logack); 305 if (x == SCMOK) 306 x = writestring(logerror); 307 if (x == SCMOK) 308 x = writemend(); 309 } else { 310 x = readmsg(MSGLOGACK); 311 if (x == SCMOK) 312 x = readint(&logack); 313 if (x == SCMOK) 314 x = readstring(&logerror); 315 if (x == SCMOK) 316 x = readmend(); 317 } 318 return (x); 319} 320/* 321 * refuse list message 322 */ 323extern TREE *refuseT; /* tree of files to refuse */ 324 325static int 326/*ARGSUSED*/ 327refuseone(TREE * t, void *v __unused) 328{ 329 return (writestring(t->Tname)); 330} 331 332int 333msgrefuse(void) 334{ 335 int x; 336 if (isserver) { 337 char *name; 338 x = readmsg(MSGREFUSE); 339 if (x == SCMOK) 340 x = readstring(&name); 341 while (x == SCMOK) { 342 if (name == NULL) 343 break; 344 (void) Tinsert(&refuseT, name, FALSE); 345 free(name); 346 name = NULL; 347 x = readstring(&name); 348 } 349 if (x == SCMOK) 350 x = readmend(); 351 } else { 352 x = writemsg(MSGREFUSE); 353 if (x == SCMOK) 354 x = Tprocess(refuseT, refuseone, NULL); 355 if (x == SCMOK) 356 x = writestring(NULL); 357 if (x == SCMOK) 358 x = writemend(); 359 } 360 return (x); 361} 362/* 363 * list files message 364 */ 365extern TREE *listT; /* tree of files to list */ 366extern time_t scantime; /* time that collection was scanned */ 367 368static int 369/*ARGSUSED*/ 370listone(TREE * t, void *v __unused) 371{ 372 int x; 373 374 x = writestring(t->Tname); 375 if (x == SCMOK) 376 x = writeint((int) t->Tmode); 377 if (x == SCMOK) 378 x = writeint((int) t->Tflags); 379 if (x == SCMOK) 380 x = writeint(t->Tmtime); 381 return (x); 382} 383 384int 385msglist(void) 386{ 387 int x; 388 if (isserver) { 389 x = writemsg(MSGLIST); 390 if (x == SCMOK) 391 x = Tprocess(listT, listone, NULL); 392 if (x == SCMOK) 393 x = writestring(NULL); 394 if (x == SCMOK) 395 x = writeint((int) scantime); 396 if (x == SCMOK) 397 x = writemend(); 398 } else { 399 char *name; 400 int mode, flags, mtime; 401 TREE *t; 402 x = readmsg(MSGLIST); 403 if (x == SCMOK) 404 x = readstring(&name); 405 while (x == SCMOK) { 406 if (name == NULL) 407 break; 408 x = readint(&mode); 409 if (x == SCMOK) 410 x = readint(&flags); 411 if (x == SCMOK) 412 x = readint(&mtime); 413 if (x != SCMOK) 414 break; 415 t = Tinsert(&listT, name, TRUE); 416 free(name); 417 t->Tmode = mode; 418 t->Tflags = flags; 419 t->Tmtime = mtime; 420 x = readstring(&name); 421 } 422 if (x == SCMOK) 423 x = readint((void *) &scantime); 424 if (x == SCMOK) 425 x = readmend(); 426 } 427 return (x); 428} 429/* 430 * files needed message 431 */ 432extern TREE *needT; /* tree of files to need */ 433 434static int 435/*ARGSUSED*/ 436needone(TREE * t, void *v __unused) 437{ 438 int x; 439 x = writestring(t->Tname); 440 if (x == SCMOK) 441 x = writeint((t->Tflags & FUPDATE) != 0); 442 return (x); 443} 444 445int 446msgneed(void) 447{ 448 int x; 449 if (isserver) { 450 char *name; 451 int update; 452 TREE *t; 453 x = readmsg(MSGNEED); 454 if (x == SCMOK) 455 x = readstring(&name); 456 while (x == SCMOK) { 457 if (name == NULL) 458 break; 459 x = readint(&update); 460 if (x != SCMOK) 461 break; 462 t = Tinsert(&needT, name, TRUE); 463 free(name); 464 if (update) 465 t->Tflags |= FUPDATE; 466 x = readstring(&name); 467 } 468 if (x == SCMOK) 469 x = readmend(); 470 } else { 471 x = writemsg(MSGNEED); 472 if (x == SCMOK) 473 x = Tprocess(needT, needone, NULL); 474 if (x == SCMOK) 475 x = writestring(NULL); 476 if (x == SCMOK) 477 x = writemend(); 478 } 479 return (x); 480} 481/* 482 * files denied message 483 */ 484extern TREE *denyT; /* tree of files to deny */ 485 486static int 487/*ARGSUSED*/ 488denyone(TREE * t, void *v __unused) 489{ 490 return (writestring(t->Tname)); 491} 492 493int 494msgdeny(void) 495{ 496 int x; 497 if (isserver) { 498 x = writemsg(MSGDENY); 499 if (x == SCMOK) 500 x = Tprocess(denyT, denyone, NULL); 501 if (x == SCMOK) 502 x = writestring(NULL); 503 if (x == SCMOK) 504 x = writemend(); 505 } else { 506 char *name; 507 x = readmsg(MSGDENY); 508 if (x == SCMOK) 509 x = readstring(&name); 510 while (x == SCMOK) { 511 if (name == NULL) 512 break; 513 (void) Tinsert(&denyT, name, FALSE); 514 free(name); 515 name = NULL; 516 x = readstring(&name); 517 } 518 if (x == SCMOK) 519 x = readmend(); 520 } 521 return (x); 522} 523/* 524 * send file message 525 */ 526int 527msgsend(void) 528{ 529 if (isserver) 530 return (readmnull(MSGSEND)); 531 return (writemnull(MSGSEND)); 532} 533/* 534 * receive file message 535 */ 536extern TREE *upgradeT; /* pointer to file being upgraded */ 537 538static int 539/*ARGSUSED*/ 540writeone(TREE * t, void *v __unused) 541{ 542 return (writestring(t->Tname)); 543} 544 545 546int 547msgrecv(int (*xferfile)(TREE *, va_list), ...) 548{ 549 va_list args; 550 int x; 551 TREE *t = upgradeT; 552 553 va_start(args, xferfile); 554 if (isserver) { 555 x = writemsg(MSGRECV); 556 if (t == NULL) { 557 if (x == SCMOK) 558 x = writestring(NULL); 559 if (x == SCMOK) 560 x = writemend(); 561 va_end(args); 562 return (x); 563 } 564 if (x == SCMOK) 565 x = writestring(t->Tname); 566 if (x == SCMOK) 567 x = writeint(t->Tmode); 568 if (t->Tmode == 0) { 569 if (x == SCMOK) 570 x = writemend(); 571 va_end(args); 572 return (x); 573 } 574 if (x == SCMOK) 575 x = writeint(t->Tflags); 576 if (x == SCMOK) 577 x = writestring(t->Tuser); 578 if (x == SCMOK) 579 x = writestring(t->Tgroup); 580 if (x == SCMOK) 581 x = writeint(t->Tmtime); 582 if (x == SCMOK) 583 x = Tprocess(t->Tlink, writeone, NULL); 584 if (x == SCMOK) 585 x = writestring(NULL); 586 if (x == SCMOK) 587 x = Tprocess(t->Texec, writeone, NULL); 588 if (x == SCMOK) 589 x = writestring(NULL); 590 if (x == SCMOK) 591 x = (*xferfile) (t, args); 592 if (x == SCMOK) 593 x = writemend(); 594 } else { 595 char *linkname, *execcmd; 596 if (t == NULL) { 597 va_end(args); 598 return (SCMERR); 599 } 600 x = readmsg(MSGRECV); 601 if (x == SCMOK) 602 x = readstring(&t->Tname); 603 if (x == SCMOK && t->Tname == NULL) { 604 x = readmend(); 605 if (x == SCMOK) 606 x = (*xferfile) (NULL, args); 607 va_end(args); 608 return (x); 609 } 610 if (x == SCMOK) 611 x = readint(&t->Tmode); 612 if (t->Tmode == 0) { 613 x = readmend(); 614 if (x == SCMOK) 615 x = (*xferfile) (t, args); 616 va_end(args); 617 return (x); 618 } 619 if (x == SCMOK) 620 x = readint(&t->Tflags); 621 if (x == SCMOK) 622 x = readstring(&t->Tuser); 623 if (x == SCMOK) 624 x = readstring(&t->Tgroup); 625 if (x == SCMOK) 626 x = readint(&t->Tmtime); 627 t->Tlink = NULL; 628 if (x == SCMOK) 629 x = readstring(&linkname); 630 while (x == SCMOK) { 631 if (linkname == NULL) 632 break; 633 (void) Tinsert(&t->Tlink, linkname, FALSE); 634 free(linkname); 635 linkname = NULL; 636 x = readstring(&linkname); 637 } 638 t->Texec = NULL; 639 if (x == SCMOK) 640 x = readstring(&execcmd); 641 while (x == SCMOK) { 642 if (execcmd == NULL) 643 break; 644 (void) Tinsert(&t->Texec, execcmd, FALSE); 645 free(execcmd); 646 execcmd = NULL; 647 x = readstring(&execcmd); 648 } 649 if (x == SCMOK) 650 x = (*xferfile) (t, args); 651 if (x == SCMOK) 652 x = readmend(); 653 } 654 va_end(args); 655 return (x); 656} 657/* 658 * protocol done message 659 */ 660extern int doneack; 661extern char *donereason; 662 663int 664msgdone(void) 665{ 666 int x; 667 668 if (protver < 6) { 669 printf("Error, msgdone should not have been called."); 670 return (SCMERR); 671 } 672 if (isserver) { 673 x = readmsg(MSGDONE); 674 if (x == SCMOK) 675 x = readint(&doneack); 676 if (x == SCMOK) 677 x = readstring(&donereason); 678 if (x == SCMOK) 679 x = readmend(); 680 } else { 681 x = writemsg(MSGDONE); 682 if (x == SCMOK) 683 x = writeint(doneack); 684 if (x == SCMOK) 685 x = writestring(donereason); 686 if (x == SCMOK) 687 x = writemend(); 688 } 689 return (x); 690} 691/* 692 * go away message 693 */ 694extern char *goawayreason; /* reason for goaway */ 695 696int 697msggoaway(void) 698{ 699 return (writemstr(MSGGOAWAY, goawayreason)); 700} 701/* 702 * cross-patch protocol message 703 */ 704extern int xargc; /* arg count for crosspatch */ 705extern char **xargv; /* arg array for crosspatch */ 706 707int 708msgxpatch(void) 709{ 710 int x; 711 int i; 712 713 if (isserver) { 714 x = readmsg(MSGXPATCH); 715 if (x != SCMOK) 716 return (x); 717 x = readint(&xargc); 718 if (x != SCMOK) 719 return (x); 720 xargc += 2; 721 xargv = (char **) calloc(sizeof(char *), (unsigned) xargc + 1); 722 if (xargv == NULL) 723 return (SCMERR); 724 for (i = 2; i < xargc; i++) { 725 x = readstring(&xargv[i]); 726 if (x != SCMOK) 727 return (x); 728 } 729 x = readmend(); 730 } else { 731 x = writemsg(MSGXPATCH); 732 if (x != SCMOK) 733 return (x); 734 x = writeint(xargc); 735 if (x != SCMOK) 736 return (x); 737 for (i = 0; i < xargc; i++) { 738 x = writestring(xargv[i]); 739 if (x != SCMOK) 740 return (x); 741 } 742 x = writemend(); 743 } 744 return (x); 745} 746/* 747 * Compression check protocol message 748 */ 749extern int docompress; /* Compress file before sending? */ 750 751int 752msgcompress(void) 753{ 754 if (isserver) 755 return (readmint(MSGCOMPRESS, &docompress)); 756 return (writemint(MSGCOMPRESS, docompress)); 757} 758