|
|
1.1 ! root 1: /* sbbsinst.c */ ! 2: ! 3: /* Synchronet installation utility */ ! 4: ! 5: /* $Id: sbbsinst.c,v 1.98 2005/11/18 05:37:29 rswindell Exp $ */ ! 6: ! 7: /**************************************************************************** ! 8: * @format.tab-size 4 (Plain Text/Source Code File Header) * ! 9: * @format.use-tabs true (see http://www.synchro.net/ptsc_hdr.html) * ! 10: * * ! 11: * Copyright 2005 Rob Swindell - http://www.synchro.net/copyright.html * ! 12: * * ! 13: * This program is free software; you can redistribute it and/or * ! 14: * modify it under the terms of the GNU General Public License * ! 15: * as published by the Free Software Foundation; either version 2 * ! 16: * of the License, or (at your option) any later version. * ! 17: * See the GNU General Public License for more details: gpl.txt or * ! 18: * http://www.fsf.org/copyleft/gpl.html * ! 19: * * ! 20: * Anonymous FTP access to the most recent released source is available at * ! 21: * ftp://vert.synchro.net, ftp://cvs.synchro.net and ftp://ftp.synchro.net * ! 22: * * ! 23: * Anonymous CVS access to the development source and modification history * ! 24: * is available at cvs.synchro.net:/cvsroot/sbbs, example: * ! 25: * cvs -d :pserver:[email protected]:/cvsroot/sbbs login * ! 26: * (just hit return, no password is necessary) * ! 27: * cvs -d :pserver:[email protected]:/cvsroot/sbbs checkout src * ! 28: * * ! 29: * For Synchronet coding style and modification guidelines, see * ! 30: * http://www.synchro.net/source.html * ! 31: * * ! 32: * You are encouraged to submit any modifications (preferably in Unix diff * ! 33: * format) via e-mail to [email protected] * ! 34: * * ! 35: * Note: If this box doesn't appear square, then you need to fix your tabs. * ! 36: ****************************************************************************/ ! 37: ! 38: #include <sys/stat.h> ! 39: #include <sys/types.h> ! 40: #include <sys/wait.h> ! 41: #include <sys/utsname.h> ! 42: #include <stdio.h> ! 43: #include <stdlib.h> ! 44: #include <string.h> ! 45: #include <unistd.h> ! 46: ! 47: /* XPDEV */ ! 48: #include "gen_defs.h" ! 49: ! 50: #include "ciolib.h" ! 51: #include "uifc.h" ! 52: #include "sbbs.h" ! 53: #include "httpio.h" ! 54: ! 55: /***************/ ! 56: /* Definitions */ ! 57: /***************/ ! 58: #define DEFAULT_CVSROOT ":pserver:[email protected]:/cvsroot/sbbs" ! 59: #define DEFAULT_DISTFILE "sbbs_src.tgz" ! 60: #define DEFAULT_LIBFILE "lib-%s.tgz" /* MUST HAVE ONE %s for system type (os-machine or just os) */ ! 61: #define DEFAULT_SYSTYPE "unix" /* If no other system type available, use this one */ ! 62: #define MAX_DISTRIBUTIONS 50 ! 63: #define MAX_DIST_FILES 10 ! 64: #define MAX_SERVERS 100 ! 65: #define MAX_FILELEN 32 ! 66: #define MAKE_ERROR "make failure.\n" ! 67: #if defined(__linux__) ! 68: #define MAKE "make" ! 69: #else ! 70: #define MAKE "gmake" ! 71: #endif ! 72: ! 73: char *distlists[]={ ! 74: "http://cvs.synchro.net/cgi-bin/viewcvs.cgi/*checkout*/src/sbbs3/install/sbbsdist.lst?rev=HEAD&content-type=text/plain" ! 75: "http://cvs-mirror.synchro.net/cgi-bin/viewcvs.cgi/*checkout*/src/sbbs3/install/sbbsdist.lst?rev=HEAD&content-type=text/plain" ! 76: ,NULL /* terminator */ ! 77: }; ! 78: ! 79: /*******************/ ! 80: /* DistList Format */ ! 81: /*******************/ ! 82: ! 83: struct server_ent_t { ! 84: char desc[78]; ! 85: char addr[256]; ! 86: }; ! 87: ! 88: typedef struct { ! 89: char version[78]; ! 90: char tag[20]; ! 91: struct server_ent_t **servers; ! 92: char **files; ! 93: int type; ! 94: char make_opts[128]; ! 95: } dist_t; ! 96: ! 97: enum { ! 98: CVS_SERVER ! 99: ,DIST_SET ! 100: ,LOCAL_FILE ! 101: }; ! 102: ! 103: /********************/ ! 104: /* Global Variables */ ! 105: /********************/ ! 106: uifcapi_t uifc; /* User Interface (UIFC) Library API */ ! 107: uifcapi_t uifc_bak; /* User Interface (UIFC) Library API */ ! 108: ! 109: struct { ! 110: char install_path[256]; ! 111: BOOL usebcc; ! 112: char cflags[256]; ! 113: BOOL debug; ! 114: BOOL symlink; ! 115: BOOL cvs; ! 116: char cvstag[256]; ! 117: char cvsroot[256]; ! 118: char make_cmdline[128]; ! 119: char sys_desc[1024]; ! 120: struct utsname name; ! 121: char sbbsuser[9]; /* Historical UName limit of 8 chars */ ! 122: char sbbsgroup[17]; /* Can't find historical limit for group names */ ! 123: #ifdef __linux__ ! 124: BOOL use_dosemu; ! 125: #endif ! 126: } params; /* Build parameters */ ! 127: ! 128: #define MAKEFILE "/tmp/SBBSmakefile" ! 129: ! 130: #define CVSCOMMAND "cvs " ! 131: ! 132: char **opt; ! 133: char tmp[256]; ! 134: char error[256]; ! 135: char cflags[MAX_PATH+1]; ! 136: char cvsroot[MAX_PATH+1]; ! 137: char distlist_rev[128]="Unspecified"; ! 138: char revision[16]; ! 139: ! 140: int backup_level=5; ! 141: BOOL keep_makefile=FALSE; ! 142: BOOL http_distlist=TRUE; ! 143: BOOL http_verbose=FALSE; ! 144: BOOL uifcinit=FALSE; ! 145: ! 146: /**************/ ! 147: /* Prototypes */ ! 148: /**************/ ! 149: void install_sbbs(dist_t *, struct server_ent_t *); ! 150: dist_t **get_distlist(void); ! 151: int choose_dist(char **opts); ! 152: int choose_server(char **opts); ! 153: ! 154: int filereadline(int sock, char *buf, size_t length, char *error) ! 155: { ! 156: char ch; ! 157: int i; ! 158: ! 159: for(i=0;1;) { ! 160: if(read(sock, &ch,1)!=1) { ! 161: if(error != NULL) ! 162: strcpy(error,"Error Reading File"); ! 163: return(-1); ! 164: } ! 165: ! 166: if(ch=='\n') ! 167: break; ! 168: ! 169: if(i<length) ! 170: buf[i++]=ch; ! 171: } ! 172: ! 173: /* Terminate at length if longer */ ! 174: if(i>length) ! 175: i=length; ! 176: ! 177: if(i>0 && buf[i-1]=='\r') ! 178: buf[--i]=0; ! 179: else ! 180: buf[i]=0; ! 181: ! 182: return(i); ! 183: } ! 184: ! 185: void bail(int code) ! 186: { ! 187: if(code) { ! 188: cputs("\nHit a key..."); ! 189: getch(); ! 190: } ! 191: if(uifcinit) ! 192: uifc.bail(); ! 193: ! 194: exit(code); ! 195: } ! 196: ! 197: void allocfail(uint size) ! 198: { ! 199: cprintf("\7Error allocating %u bytes of memory.\n",size); ! 200: bail(1); ! 201: } ! 202: ! 203: int main(int argc, char **argv) ! 204: { ! 205: char** mopt; ! 206: char* p; ! 207: int i=0; ! 208: int main_dflt=0; ! 209: char str[129]; ! 210: dist_t **distlist; ! 211: int dist=0; ! 212: int server=0; ! 213: int ciolib_mode=CIOLIB_MODE_AUTO; ! 214: int tmode=C80; ! 215: ! 216: /************/ ! 217: /* Defaults */ ! 218: /************/ ! 219: SAFECOPY(params.install_path,"/usr/local/sbbs"); ! 220: SAFECOPY(params.make_cmdline,MAKE " install -f install/GNUmakefile"); ! 221: params.usebcc=FALSE; ! 222: SAFECOPY(params.cflags,""); ! 223: params.debug=FALSE; ! 224: params.symlink=TRUE; ! 225: params.cvs=TRUE; ! 226: SAFECOPY(params.cvstag,"HEAD"); ! 227: SAFECOPY(params.cvsroot,DEFAULT_CVSROOT); ! 228: if((p=getenv("USER"))!=NULL) ! 229: SAFECOPY(params.sbbsuser,p); ! 230: if((p=getenv("GROUP"))!=NULL) ! 231: SAFECOPY(params.sbbsgroup,p); ! 232: #ifdef __linux__ ! 233: params.use_dosemu=FALSE; ! 234: #endif ! 235: ! 236: sscanf("$Revision: 1.98 $", "%*s %s", revision); ! 237: umask(077); ! 238: ! 239: printf("\nSynchronet Installation %s-%s\n",revision,PLATFORM_DESC); ! 240: ! 241: memset(&uifc,0,sizeof(uifc)); ! 242: ! 243: uifc.esc_delay=25; ! 244: ! 245: for(i=1;i<argc;i++) { ! 246: if(argv[i][0]=='-' ! 247: #ifndef __unix__ ! 248: || argv[i][0]=='/' ! 249: #endif ! 250: ) ! 251: switch(toupper(argv[i][1])) { ! 252: case 'C': ! 253: uifc.mode|=UIFC_COLOR; ! 254: break; ! 255: case 'L': ! 256: uifc.scrn_len=atoi(argv[i]+2); ! 257: break; ! 258: case 'E': ! 259: uifc.esc_delay=atoi(argv[i]+2); ! 260: break; ! 261: case 'F': ! 262: case 'H': ! 263: http_verbose=TRUE; ! 264: break; ! 265: case 'N': ! 266: http_distlist=FALSE; ! 267: break; ! 268: case 'I': ! 269: switch(toupper(argv[i][2])) { ! 270: case 'A': ! 271: ciolib_mode=CIOLIB_MODE_ANSI; ! 272: break; ! 273: case 'C': ! 274: ciolib_mode=CIOLIB_MODE_CURSES; ! 275: break; ! 276: case 0: ! 277: printf("NOTICE: The -i option is depreciated, use -if instead\r\n"); ! 278: SLEEP(2000); ! 279: case 'F': ! 280: ciolib_mode=CIOLIB_MODE_CURSES_IBM; ! 281: break; ! 282: case 'X': ! 283: ciolib_mode=CIOLIB_MODE_X; ! 284: break; ! 285: case 'W': ! 286: ciolib_mode=CIOLIB_MODE_CONIO; ! 287: break; ! 288: default: ! 289: goto USAGE; ! 290: } ! 291: break; ! 292: case 'V': ! 293: tmode=atoi(argv[i]+2); ! 294: break; ! 295: default: ! 296: USAGE: ! 297: printf("\nusage: %s [ctrl_dir] [options]" ! 298: "\n\noptions:\n\n" ! 299: "-n = do not HTTP-download distribution list\n" ! 300: "-h = run in HTTP-verbose (debug) mode\n" ! 301: "-c = force color mode\n" ! 302: #ifdef USE_CURSES ! 303: "-e# = set escape delay to #msec\n" ! 304: #endif ! 305: "-iX = set interface mode to X (default=auto) where X is one of:\r\n" ! 306: #ifdef __unix__ ! 307: " X = X11 mode\r\n" ! 308: " C = Curses mode\r\n" ! 309: " F = Curses mode with forced IBM charset\r\n" ! 310: #else ! 311: " W = Win32 native mode\r\n" ! 312: #endif ! 313: " A = ANSI mode\r\n" ! 314: "-v# = set video mode to #\n" ! 315: "-l# = set screen lines to #\n" ! 316: ,argv[0] ! 317: ); ! 318: exit(0); ! 319: } ! 320: } ! 321: ! 322: i=initciolib(ciolib_mode); ! 323: if(i!=0) { ! 324: printf("ciolib library init returned error %d\n",i); ! 325: exit(1); ! 326: } ! 327: textmode(tmode); ! 328: uifc.size=sizeof(uifc); ! 329: memcpy(&uifc_bak,&uifc,sizeof(uifc)); ! 330: i=uifcini32(&uifc); /* curses/conio/X/ANSI */ ! 331: if(i!=0) { ! 332: cprintf("uifc library init returned error %d\n",i); ! 333: bail(1); ! 334: } ! 335: uifcinit=TRUE; ! 336: ! 337: if(uname(¶ms.name)<0) { ! 338: SAFECOPY(params.name.machine,"Unknown"); ! 339: SAFECOPY(params.name.sysname,params.name.machine); ! 340: } ! 341: sprintf(params.sys_desc,"%s-%s",params.name.sysname,params.name.machine); ! 342: ! 343: distlist=get_distlist(); ! 344: ! 345: if(distlist==NULL) { ! 346: cprintf("No installation files or distribution list present!\n"); ! 347: bail(1); ! 348: } ! 349: ! 350: if((opt=(char **)malloc(sizeof(char *)*(MAX_OPTS+1)))==NULL) ! 351: allocfail(sizeof(char *)*(MAX_OPTS+1)); ! 352: for(i=0;i<(MAX_OPTS+1);i++) ! 353: if((opt[i]=(char *)malloc(MAX_OPLN))==NULL) ! 354: allocfail(MAX_OPLN); ! 355: ! 356: if((mopt=(char **)malloc(sizeof(char *)*MAX_OPTS))==NULL) ! 357: allocfail(sizeof(char *)*MAX_OPTS); ! 358: for(i=0;i<MAX_OPTS;i++) ! 359: if((mopt[i]=(char *)malloc(MAX_OPLN))==NULL) ! 360: allocfail(MAX_OPLN); ! 361: ! 362: sprintf(str,"Synchronet Installation %s-%s",revision,PLATFORM_DESC); ! 363: if(uifc.scrn(str)) { ! 364: cprintf(" USCRN (len=%d) failed!\n",uifc.scrn_len+1); ! 365: bail(1); ! 366: } ! 367: ! 368: while(1) { ! 369: i=0; ! 370: sprintf(mopt[i++],"%-27.27s%s","Distribution",distlist[dist]->version); ! 371: sprintf(mopt[i++],"%-27.27s%s","Server" ! 372: ,(distlist[dist]->type==LOCAL_FILE?"Local Files":distlist[dist]->servers[server]->desc)); ! 373: sprintf(mopt[i++],"%-27.27s%s","System Type",params.sys_desc); ! 374: sprintf(mopt[i++],"%-27.27s%s","Install Path",params.install_path); ! 375: sprintf(mopt[i++],"%-27.27s%s","Compiler",params.usebcc?"Borland":"GNU"); ! 376: sprintf(mopt[i++],"%-27.27s%s","Compiler Flags",params.cflags); ! 377: sprintf(mopt[i++],"%-27.27s%s","Debug Build",params.debug?"Yes":"No"); ! 378: sprintf(mopt[i++],"%-27.27s%s","Symlink Binaries",params.symlink?"Yes":"No"); ! 379: sprintf(mopt[i++],"%-27.27s%s","Make Command-line",params.make_cmdline); ! 380: sprintf(mopt[i++],"%-27.27s%s","File Owner",params.sbbsuser); ! 381: sprintf(mopt[i++],"%-27.27s%s","File Group",params.sbbsgroup); ! 382: #ifdef __linux__ ! 383: sprintf(mopt[i++],"%-27.27s%s","Integrate DOSEmu support",params.use_dosemu?"Yes":"No"); ! 384: #endif ! 385: sprintf(mopt[i++],"%-27.27s","Start Installation..."); ! 386: mopt[i][0]=0; ! 387: ! 388: sprintf(str,"Synchronet Installation - Distribution List %s",distlist_rev); ! 389: uifc.helpbuf= "`Synchronet Installation:`\n" ! 390: "\nToDo: Add help."; ! 391: switch(uifc.list(WIN_ESC|WIN_MID|WIN_ACT|WIN_ORG,0,0,70,&main_dflt,0 ! 392: ,str,mopt)) { ! 393: case 0: ! 394: i=choose_dist((char **)distlist); ! 395: if(i>=0) { ! 396: server=0; ! 397: dist=i; ! 398: } ! 399: break; ! 400: case 1: ! 401: if(distlist[dist]->type != LOCAL_FILE) { ! 402: i=choose_server((char **)distlist[dist]->servers); ! 403: if(i>=0) ! 404: server=i; ! 405: } ! 406: break; ! 407: case 2: ! 408: uifc.helpbuf= "`System Type`\n" ! 409: "\nToDo: Add help."; ! 410: uifc.input(WIN_MID,0,0,"System Type",params.sys_desc,40,K_EDIT); ! 411: break; ! 412: case 3: ! 413: uifc.helpbuf= "`Install Path`\n" ! 414: "\n" ! 415: "\nPath to install the Synchronet BBS system into." ! 416: "\nSome common paths:" ! 417: "\n /sbbs" ! 418: "\n /usr/local/sbbs" ! 419: "\n /opt/sbbs" ! 420: "\n /home/bbs/sbbs"; ! 421: uifc.input(WIN_MID,0,0,"",params.install_path,50,K_EDIT); ! 422: break; ! 423: case 4: ! 424: strcpy(opt[0],"Borland"); ! 425: strcpy(opt[1],"GNU"); ! 426: opt[2][0]=0; ! 427: i=params.usebcc?0:1; ! 428: uifc.helpbuf= "`Which Compiler`\n" ! 429: "\nToDo: Add help."; ! 430: i=uifc.list(WIN_MID|WIN_SAV,0,0,0,&i,0 ! 431: ,"Compiler",opt); ! 432: if(!i) ! 433: params.usebcc=TRUE; ! 434: else if(i==1) ! 435: params.usebcc=FALSE; ! 436: i=0; ! 437: break; ! 438: case 5: ! 439: uifc.helpbuf= "`Compiler Flags`\n" ! 440: "\nToDo: Add help."; ! 441: uifc.input(WIN_MID,0,0,"Additional Compiler Flags",params.cflags,40,K_EDIT); ! 442: break; ! 443: case 6: ! 444: strcpy(opt[0],"Yes"); ! 445: strcpy(opt[1],"No"); ! 446: opt[2][0]=0; ! 447: i=params.debug?0:1; ! 448: uifc.helpbuf= "`Debug Build`\n" ! 449: "\nToDo: Add help."; ! 450: i=uifc.list(WIN_MID|WIN_SAV,0,0,0,&i,0 ! 451: ,"Build a Debug Version",opt); ! 452: if(!i) ! 453: params.debug=TRUE; ! 454: else if(i==1) ! 455: params.debug=FALSE; ! 456: i=0; ! 457: break; ! 458: case 7: ! 459: strcpy(opt[0],"Yes"); ! 460: strcpy(opt[1],"No"); ! 461: opt[2][0]=0; ! 462: i=params.symlink?0:1; ! 463: uifc.helpbuf= "`Symlink Binaries:`\n" ! 464: "\n" ! 465: "\nShould the installer create symlinks to the binaries or copy them from" ! 466: "\nthe compiled location?"; ! 467: i=uifc.list(WIN_MID|WIN_SAV,0,0,0,&i,0 ! 468: ,"Symlink Binaries",opt); ! 469: if(!i) ! 470: params.symlink=TRUE; ! 471: else if(i==1) ! 472: params.symlink=FALSE; ! 473: i=0; ! 474: break; ! 475: case 8: ! 476: uifc.helpbuf= "`Make Command-line`\n" ! 477: "\n"; ! 478: uifc.input(WIN_MID,0,0,"",params.make_cmdline,65,K_EDIT); ! 479: break; ! 480: case 9: ! 481: uifc.helpbuf= "`File Owner`\n" ! 482: "\n"; ! 483: uifc.input(WIN_MID,0,0,"",params.sbbsuser,8,K_EDIT); ! 484: break; ! 485: case 10: ! 486: uifc.helpbuf= "`File Group`\n" ! 487: "\n"; ! 488: uifc.input(WIN_MID,0,0,"",params.sbbsgroup,32,K_EDIT); ! 489: break; ! 490: #ifdef __linux__ ! 491: case 11: ! 492: strcpy(opt[0],"Yes"); ! 493: strcpy(opt[1],"No"); ! 494: opt[2][0]=0; ! 495: i=params.use_dosemu?0:1; ! 496: uifc.helpbuf= "`Include DOSEmu Support`\n" ! 497: "\nToDo: Add help."; ! 498: i=uifc.list(WIN_MID|WIN_SAV,0,0,0,&i,0 ! 499: ,"Integrate DOSEmu support into Synchronet?",opt); ! 500: if(!i) ! 501: params.use_dosemu=TRUE; ! 502: else if(i==1) ! 503: params.use_dosemu=FALSE; ! 504: i=0; ! 505: break; ! 506: case 12: ! 507: #else ! 508: case 11: ! 509: #endif ! 510: install_sbbs(distlist[dist],distlist[dist]->type==LOCAL_FILE?NULL:distlist[dist]->servers[server]); ! 511: bail(0); ! 512: break; ! 513: case -1: ! 514: i=0; ! 515: strcpy(opt[0],"Yes"); ! 516: strcpy(opt[1],"No"); ! 517: opt[2][0]=0; ! 518: uifc.helpbuf= "`Exit Synchronet Install:`\n" ! 519: "\n" ! 520: "\nIf you want to exit the Synchronet installation utility, select `Yes`." ! 521: "\nOtherwise, select `No` or hit ~ ESC ~."; ! 522: i=uifc.list(WIN_MID,0,0,0,&i,0,"Exit Synchronet Install",opt); ! 523: if(!i) ! 524: bail(0); ! 525: break; ! 526: } ! 527: } ! 528: } ! 529: ! 530: /* Little wrapper for system calls */ ! 531: int exec(char* cmd) ! 532: { ! 533: int in_pipe[2]; ! 534: int out_pipe[2]; ! 535: int err_pipe[2]; ! 536: int wait_done; ! 537: pid_t pid; ! 538: struct text_info err_window; ! 539: struct text_info out_window; ! 540: int avail; ! 541: struct timeval timeout; ! 542: char *buf; ! 543: int i,retval; ! 544: ! 545: if(pipe(out_pipe)!=0 || pipe(in_pipe)!=0 || pipe(err_pipe)!=0) { ! 546: cputs("\nError creating I/O pipes"); ! 547: bail(1); ! 548: } ! 549: ! 550: if((pid=FORK())==-1) { ! 551: return(-1); ! 552: } ! 553: ! 554: if(pid==0) { ! 555: char *argv[4]; ! 556: /* Child Process */ ! 557: close(in_pipe[1]); /* close write-end of pipe */ ! 558: dup2(in_pipe[0],0); /* redirect stdin */ ! 559: close(in_pipe[0]); /* close excess file descriptor */ ! 560: ! 561: close(out_pipe[0]); /* close read-end of pipe */ ! 562: dup2(out_pipe[1],1); /* stdout */ ! 563: close(out_pipe[1]); /* close excess file descriptor */ ! 564: setvbuf(stdout,NULL,_IONBF,0); /* Make stdout unbuffered */ ! 565: ! 566: close(err_pipe[0]); /* close read-end of pipe */ ! 567: dup2(err_pipe[1],2); /* stderr */ ! 568: close(err_pipe[1]); /* close excess file descriptor */ ! 569: setvbuf(stderr,NULL,_IONBF,0); /* Make stderr unbuffered */ ! 570: ! 571: argv[0]="/bin/sh"; ! 572: argv[1]="-c"; ! 573: argv[2]=cmd; ! 574: argv[3]=NULL; ! 575: execvp(argv[0],argv); ! 576: _exit(1); ! 577: } ! 578: ! 579: close(in_pipe[0]); /* close excess file descriptor */ ! 580: close(out_pipe[1]); /* close excess file descriptor */ ! 581: close(err_pipe[1]); /* close excess file descriptor */ ! 582: ! 583: i=waitpid(pid, &retval, WNOHANG)!=0; ! 584: wait_done=(i!=0); ! 585: if(i==-1) ! 586: retval=-1; ! 587: gettextinfo(&err_window); ! 588: clrscr(); ! 589: gotoxy(1,1); ! 590: cprintf("Running command: %s",cmd); ! 591: gotoxy(1,2); ! 592: clreol(); ! 593: textattr(RED<<4|WHITE); ! 594: cputs("Error Output:"); ! 595: window(1,3,err_window.screenwidth,7); ! 596: clrscr(); ! 597: gotoxy(1,1); ! 598: gettextinfo(&err_window); ! 599: window(1,1,err_window.screenwidth,err_window.screenheight); ! 600: gotoxy(1,8); ! 601: textattr(LIGHTGRAY); ! 602: cputs("Output:"); ! 603: window(1,9,err_window.screenwidth,err_window.screenheight); ! 604: clrscr(); ! 605: gotoxy(1,1); ! 606: gettextinfo(&out_window); ! 607: _wscroll=1; ! 608: while(!wait_done) { ! 609: fd_set ibits; ! 610: int high_fd; ! 611: ! 612: i=waitpid(pid, &retval, WNOHANG)!=0; ! 613: wait_done=(i!=0); ! 614: if(i==-1) ! 615: retval=-1; ! 616: FD_ZERO(&ibits); ! 617: FD_SET(err_pipe[0],&ibits); ! 618: high_fd=err_pipe[0]; ! 619: FD_SET(out_pipe[0],&ibits); ! 620: if(out_pipe[0]>err_pipe[0]) ! 621: high_fd=out_pipe[0]; ! 622: timeout.tv_sec=0; ! 623: timeout.tv_usec=1000; ! 624: if(select(high_fd+1,&ibits,NULL,NULL,&timeout)>0) { ! 625: if(FD_ISSET(err_pipe[0],&ibits)) { ! 626: /* Got some stderr input */ ! 627: window(err_window.winleft,err_window.wintop,err_window.winright,err_window.winbottom); ! 628: gotoxy(err_window.curx,err_window.cury); ! 629: textattr(err_window.attribute); ! 630: avail=0; ! 631: if(ioctl(err_pipe[0],FIONREAD,(void *)&avail)!=-1 && avail > 0) { ! 632: int got=0; ! 633: buf=(char *)malloc(avail+1); ! 634: while(got<avail) { ! 635: i=read(err_pipe[0], buf+got, avail-got); ! 636: if(i>0) { ! 637: got+=i; ! 638: } ! 639: if(i==-1) ! 640: break; ! 641: } ! 642: if(got==avail) { ! 643: buf[avail]=0; ! 644: cputs(buf); ! 645: } ! 646: free(buf); ! 647: } ! 648: gettextinfo(&err_window); ! 649: } ! 650: if(FD_ISSET(out_pipe[0],&ibits)) { ! 651: /* Got some stdout input */ ! 652: window(out_window.winleft,out_window.wintop,out_window.winright,out_window.winbottom); ! 653: gotoxy(out_window.curx,out_window.cury); ! 654: textattr(out_window.attribute); ! 655: avail=0; ! 656: if(ioctl(out_pipe[0],FIONREAD,(void *)&avail)!=-1 && avail > 0) { ! 657: int got=0; ! 658: buf=(char *)malloc(avail+1); ! 659: while(got<avail) { ! 660: i=read(out_pipe[0], buf+got, avail-got); ! 661: if(i>0) { ! 662: got+=i; ! 663: } ! 664: if(i==-1) ! 665: break; ! 666: } ! 667: if(got==avail) { ! 668: buf[avail]=0; ! 669: cputs(buf); ! 670: } ! 671: free(buf); ! 672: } ! 673: gettextinfo(&out_window); ! 674: } ! 675: } ! 676: } ! 677: ! 678: return(retval); ! 679: } ! 680: ! 681: int view_file(char *filename, char *title) ! 682: { ! 683: char str[1024]; ! 684: int buffile; ! 685: int j; ! 686: char *buf; ! 687: ! 688: if(fexist(filename)) { ! 689: if((buffile=sopen(filename,O_RDONLY,SH_DENYWR))>=0) { ! 690: j=filelength(buffile); ! 691: if((buf=(char *)malloc(j+1))!=NULL) { ! 692: read(buffile,buf,j); ! 693: close(buffile); ! 694: *(buf+j)=0; ! 695: uifc.showbuf(WIN_MID|WIN_PACK|WIN_FAT,1,1,80,uifc.scrn_len,title,buf,NULL,NULL); ! 696: free(buf); ! 697: return(0); ! 698: } ! 699: close(buffile); ! 700: uifc.msg("Error allocating memory for the file"); ! 701: return(3); ! 702: } ! 703: sprintf(str,"Error opening %s",title); ! 704: uifc.msg(str); ! 705: return(1); ! 706: } ! 707: sprintf(str,"%s does not exists",title); ! 708: uifc.msg(str); ! 709: return(2); ! 710: } ! 711: ! 712: /* Some jiggery-pokery here to avoid having to enter the CVS password */ ! 713: /* fprintf(makefile,"\tif(grep '%s' -q ~/.cvspass) then echo \"%s A\" >> ~/.cvspass; fi\n", ! 714: * params.cvsroot,params.cvsroot); ! 715: * ! 716: * Actually, it looks like you don't NEED to login if the password is blank... huh. ! 717: */ ! 718: ! 719: void install_sbbs(dist_t *dist,struct server_ent_t *server) { ! 720: char cmd[MAX_PATH+1]; ! 721: char str[1024]; ! 722: char fname[MAX_PATH+1]; ! 723: char dstfname[MAX_PATH+1]; ! 724: char sbbsdir[9+MAX_PATH]; ! 725: char cvstag[7+MAX_PATH]; ! 726: char buf[4096]; ! 727: char url[MAX_PATH+1]; ! 728: char path[MAX_PATH+1]; ! 729: char sbbsuser[128]; ! 730: char sbbsgroup[128]; ! 731: int i; ! 732: int fout,ret1,ret2; ! 733: size_t flen; ! 734: long offset; ! 735: int remote; ! 736: char http_error[128]; ! 737: ! 738: if(params.debug) ! 739: putenv("DEBUG=1"); ! 740: else ! 741: putenv("RELEASE=1"); ! 742: ! 743: if(params.symlink) ! 744: putenv("SYMLINK=1"); ! 745: ! 746: sprintf(sbbsdir,"SBBSDIR=%s",params.install_path); ! 747: putenv(sbbsdir); ! 748: if(params.sbbsuser[0]) { ! 749: sprintf(sbbsuser,"SBBSUSER=%s",params.sbbsuser); ! 750: putenv(sbbsuser); ! 751: } ! 752: if(params.sbbsgroup[0]) { ! 753: sprintf(sbbsgroup,"SBBSGROUP=%s",params.sbbsgroup); ! 754: putenv(sbbsgroup); ! 755: } ! 756: #ifdef __linux__ ! 757: if(params.use_dosemu==TRUE) { ! 758: putenv("USE_DOSEMU=1"); ! 759: } ! 760: #endif ! 761: ! 762: if(params.usebcc) ! 763: putenv("bcc=1"); ! 764: ! 765: sprintf(path,"%s",FULLPATH(str,"./",sizeof(str))); ! 766: if(mkdir(params.install_path,0777)&&errno!=EEXIST) { ! 767: sprintf(str,"Could not create install %s!",params.install_path); ! 768: uifc.msg(str); ! 769: bail(EXIT_FAILURE); ! 770: } ! 771: if(chdir(params.install_path)) { ! 772: sprintf(str,"Could not change to %s (%d)!",params.install_path,errno); ! 773: uifc.msg(str); ! 774: bail(EXIT_FAILURE); ! 775: } ! 776: uifc.bail(); ! 777: uifcinit=FALSE; ! 778: switch (dist->type) { ! 779: case CVS_SERVER: ! 780: sprintf(cvstag,"CVSTAG=%s",dist->tag); ! 781: putenv(cvstag); ! 782: sprintf(cmd,"cvs -d %s co -r %s install",server->addr,dist->tag); ! 783: if(exec(cmd)) { ! 784: cprintf("Could not checkout install makefile.\n"); ! 785: bail(EXIT_FAILURE); ! 786: } ! 787: sprintf(cmd,"%s %s",params.make_cmdline,dist->make_opts); ! 788: if(exec(cmd)) { ! 789: cprintf(MAKE_ERROR); ! 790: bail(EXIT_FAILURE); ! 791: } ! 792: break; ! 793: case DIST_SET: ! 794: for(i=0;dist->files[i][0];i++) { ! 795: sprintf(fname,dist->files[i],params.sys_desc); ! 796: SAFECOPY(dstfname,fname); ! 797: if((fout=open(fname,O_WRONLY|O_TRUNC|O_CREAT,S_IRUSR|S_IWUSR))<0) { ! 798: cprintf("Could not download distfile to %s (%d)\n",fname,errno); ! 799: bail(EXIT_FAILURE); ! 800: } ! 801: sprintf(url,"%s%s",server->addr,fname); ! 802: if((remote=http_get_fd(url,&flen,NULL))<0) { ! 803: /* retry without machine type in name */ ! 804: SAFECOPY(str,fname); ! 805: sprintf(fname,dist->files[i],params.name.sysname); ! 806: sprintf(url,"%s%s",server->addr,fname); ! 807: if(stricmp(str,fname)==0 /* no change in name? */ ! 808: || (remote=http_get_fd(url,&flen,NULL))<0) { ! 809: /* retry using default system-type for system name */ ! 810: sprintf(fname,dist->files[i],DEFAULT_SYSTYPE); ! 811: if((remote=http_get_fd(url,&flen,http_error))<0) { ! 812: cprintf("Cannot get distribution file %s!\n",fname); ! 813: cprintf("%s\n- %s\n",url,http_error); ! 814: close(fout); ! 815: unlink(dstfname); ! 816: bail(EXIT_FAILURE); ! 817: } ! 818: } ! 819: } ! 820: cprintf("Downloading %s ",url); ! 821: offset=0; ! 822: while((ret1=read(remote,buf,sizeof(buf)))>0) { ! 823: ret2=write(fout,buf,ret1); ! 824: if(ret2!=ret1) { ! 825: cprintf("\n!ERROR %d writing to %s\n",errno,dstfname); ! 826: close(fout); ! 827: unlink(dstfname); ! 828: bail(EXIT_FAILURE); ! 829: } ! 830: offset+=ret2; ! 831: if(flen) ! 832: cprintf("\b\b\b\b\b\b\b\b\b\b%3lu%% ",(long)(((float)offset/(float)flen)*100.0)); ! 833: else ! 834: cprintf("\b\b\b\b\b\b\b\b\b\b%10lu",offset); ! 835: } ! 836: cprintf("\n"); ! 837: if(ret1<0) { ! 838: cprintf("!ERROR downloading %s\n",fname); ! 839: close(fout); ! 840: unlink(dstfname); ! 841: bail(EXIT_FAILURE); ! 842: } ! 843: close(fout); ! 844: sprintf(cmd,"gzip -dc %s | tar -xvf -",dstfname); ! 845: if(exec(cmd)) { ! 846: cprintf("Error extracting %s\n",dstfname); ! 847: unlink(dstfname); ! 848: bail(EXIT_FAILURE); ! 849: } ! 850: unlink(dstfname); ! 851: } ! 852: sprintf(cmd,"%s %s",params.make_cmdline,dist->make_opts); ! 853: if(exec(cmd)) { ! 854: cprintf(MAKE_ERROR); ! 855: bail(EXIT_FAILURE); ! 856: } ! 857: break; ! 858: case LOCAL_FILE: ! 859: for(i=0;dist->files[i][0];i++) { ! 860: sprintf(cmd,"gzip -dc %s/%s | tar -xvf -",path,dist->files[i]); ! 861: if(exec(cmd)) { ! 862: cprintf("Error extracting %s/%s\n",path,dist->files[i]); ! 863: bail(EXIT_FAILURE); ! 864: } ! 865: } ! 866: sprintf(cmd,"%s %s",params.make_cmdline,dist->make_opts); ! 867: if(exec(cmd)) { ! 868: cprintf(MAKE_ERROR); ! 869: bail(EXIT_FAILURE); ! 870: } ! 871: break; ! 872: } ! 873: ! 874: memcpy(&uifc,&uifc_bak,sizeof(uifc)); ! 875: i=uifcini32(&uifc); /* curses/conio/X/ANSI */ ! 876: if(i!=0) { ! 877: cprintf("uifc library init returned error %d\n",i); ! 878: bail(EXIT_FAILURE); ! 879: } ! 880: uifcinit=TRUE; ! 881: sprintf(str,"Synchronet Installation %s-%s",revision,PLATFORM_DESC); ! 882: if(uifc.scrn(str)) { ! 883: cprintf(" USCRN (len=%d) failed!\n",uifc.scrn_len+1); ! 884: bail(EXIT_FAILURE); ! 885: } ! 886: sprintf(cmd,"%s/docs/sbbscon.txt",params.install_path); ! 887: view_file(cmd,"*nix console documentation"); ! 888: uifc.bail(); ! 889: uifcinit=FALSE; ! 890: cprintf("Synchronet has been successfully installed to:\n\t%s\n",params.install_path); ! 891: cprintf("Documentation files in:\n\t%s/docs\n",params.install_path); ! 892: cprintf("Configuration files in:\n\t%s/ctrl\n",params.install_path); ! 893: cprintf("Executable program files in:\n\t%s/exec\n",params.install_path); ! 894: bail(EXIT_SUCCESS); ! 895: } ! 896: ! 897: dist_t ** ! 898: get_distlist(void) ! 899: { ! 900: int i; ! 901: char in_line[256]; ! 902: dist_t **dist; ! 903: char **file=NULL; ! 904: struct server_ent_t **server=NULL; ! 905: int r=0; ! 906: int f=0; ! 907: int s=0; ! 908: char* p; ! 909: char* tp; ! 910: int list=-1; ! 911: char sep[2]={'\t',0}; ! 912: char str[1024]; ! 913: char errors[sizeof(distlists)/sizeof(char*)][128]; ! 914: int (*readline) (int sock, char *buf, size_t length, char *error)=NULL; ! 915: ! 916: memset(errors,0,sizeof(errors)); ! 917: if((dist=(dist_t **)malloc(sizeof(void *)*MAX_DISTRIBUTIONS))==NULL) ! 918: allocfail(sizeof(void *)*MAX_DISTRIBUTIONS); ! 919: for(i=0;i<MAX_DISTRIBUTIONS;i++) ! 920: if((dist[i]=(void *)malloc(sizeof(dist_t)))==NULL) ! 921: allocfail(sizeof(dist_t)); ! 922: ! 923: sprintf(str,DEFAULT_LIBFILE,params.sys_desc); ! 924: if(!fexistcase(str)) /* use lib-linux.tgz if lib-linux-i686.tgz doesn't exist */ ! 925: sprintf(str,DEFAULT_LIBFILE,params.name.sysname); ! 926: if(!fexistcase(str)) /* use lib-unix.tgz if all else fails */ ! 927: sprintf(str,DEFAULT_LIBFILE,DEFAULT_SYSTYPE); ! 928: if(fexist(DEFAULT_DISTFILE) && fexistcase(str)) { ! 929: if((file=(char **)malloc(sizeof(char *)*MAX_DIST_FILES))==NULL) ! 930: allocfail(sizeof(char *)*MAX_DIST_FILES); ! 931: for(i=0;i<MAX_DIST_FILES;i++) ! 932: if((file[i]=(char *)malloc(MAX_FILELEN))==NULL) ! 933: allocfail(MAX_FILELEN); ! 934: server=NULL; ! 935: f=0; ! 936: s=0; ! 937: ! 938: memset(dist[r],0,sizeof(dist_t)); ! 939: sprintf(dist[r]->version,"%s (Local)",VERSION); ! 940: dist[r]->type=LOCAL_FILE; ! 941: dist[r]->servers=server; ! 942: dist[r]->files=file; ! 943: strcpy(dist[r]->make_opts,"NOCVS=1"); ! 944: r++; ! 945: strcpy(file[f++],DEFAULT_DISTFILE); ! 946: strcpy(file[f++],str); ! 947: } ! 948: ! 949: if(http_distlist) { ! 950: uifc.pop("Getting distributions"); ! 951: for(i=0;distlists[i]!=NULL;i++) { ! 952: if((list=http_get_fd(distlists[i],NULL,errors[i]))>=0) { ! 953: readline=sockreadline; ! 954: break; ! 955: } ! 956: } ! 957: } ! 958: if(list<0) { ! 959: if(http_distlist) ! 960: uifc.pop(NULL); ! 961: uifc.pop("Loading distlist"); ! 962: if((list=open("./sbbsdist.lst",O_RDONLY))<0) ! 963: list=open("../sbbsdist.lst",O_RDONLY); ! 964: if(list>=0) ! 965: readline=filereadline; ! 966: } ! 967: if(list<0) { ! 968: cprintf("Cannot get distribution list!\n"); ! 969: for(i=0;distlists[i]!=NULL;i++) ! 970: cprintf("%s\n- %s\n",distlists[i],errors[i]); ! 971: bail(EXIT_FAILURE); ! 972: } ! 973: ! 974: while(readline != NULL && list>=0 && (readline(list,in_line,sizeof(in_line),NULL)>=0)) { ! 975: i=strlen(in_line); ! 976: while(i>0 && in_line[i]<=' ') ! 977: in_line[i--]=0; ! 978: ! 979: if(in_line[0]=='D') { ! 980: strcpy(str,in_line); ! 981: sep[0]=' '; ! 982: p=strtok(str,sep); ! 983: p=strtok(NULL,sep); ! 984: if(strstr(p,params.sys_desc)==NULL) ! 985: break; ! 986: sep[0]='\n'; ! 987: p=strtok(NULL,sep); ! 988: strcpy(in_line,p); ! 989: } ! 990: ! 991: switch(in_line[0]) { ! 992: case 'R': /* revision */ ! 993: sscanf(in_line+2, "%*s %s", distlist_rev); ! 994: break; ! 995: case 'C': ! 996: if(file!=NULL) ! 997: file[f]=""; ! 998: if(server!=NULL) ! 999: memset(server[s],0,sizeof(struct server_ent_t)); ! 1000: ! 1001: file=NULL; ! 1002: ! 1003: if((server=(struct server_ent_t **)malloc(sizeof(void *)*MAX_SERVERS))==NULL) ! 1004: allocfail(sizeof(struct server_ent_t *)*MAX_SERVERS); ! 1005: for(i=0;i<MAX_SERVERS;i++) ! 1006: if((server[i]=(struct server_ent_t *)malloc(sizeof(struct server_ent_t)))==NULL) ! 1007: allocfail(64); ! 1008: f=0; ! 1009: s=0; ! 1010: ! 1011: memset(dist[r],0,sizeof(dist_t)); ! 1012: strcpy(dist[r]->version,in_line+2); ! 1013: dist[r]->type=CVS_SERVER; ! 1014: dist[r]->servers=server; ! 1015: r++; ! 1016: break; ! 1017: case 'T': ! 1018: if(file!=NULL) ! 1019: file[f]=""; ! 1020: if(server!=NULL) ! 1021: memset(server[s],0,sizeof(struct server_ent_t)); ! 1022: ! 1023: if((file=(char **)malloc(sizeof(char *)*MAX_DIST_FILES))==NULL) ! 1024: allocfail(sizeof(char *)*MAX_DIST_FILES); ! 1025: for(i=0;i<MAX_DIST_FILES;i++) ! 1026: if((file[i]=(char *)malloc(MAX_FILELEN))==NULL) ! 1027: allocfail(MAX_FILELEN); ! 1028: ! 1029: if((server=(struct server_ent_t **)malloc(sizeof(struct server_ent_t *)*MAX_SERVERS))==NULL) ! 1030: allocfail(sizeof(struct server_ent_t *)*MAX_SERVERS); ! 1031: for(i=0;i<MAX_SERVERS;i++) ! 1032: if((server[i]=(struct server_ent_t *)malloc(sizeof(struct server_ent_t)))==NULL) ! 1033: allocfail(64); ! 1034: f=0; ! 1035: s=0; ! 1036: ! 1037: memset(dist[r],0,sizeof(dist_t)); ! 1038: strcpy(dist[r]->version,in_line+2); ! 1039: dist[r]->type=DIST_SET; ! 1040: dist[r]->servers=server; ! 1041: dist[r]->files=file; ! 1042: r++; ! 1043: break; ! 1044: case 'f': ! 1045: strcpy(file[f++],in_line+2); ! 1046: break; ! 1047: case 't': ! 1048: SAFECOPY(dist[r-1]->tag,in_line+2); ! 1049: break; ! 1050: case 'm': ! 1051: SAFECOPY(dist[r-1]->make_opts,in_line+2); ! 1052: break; ! 1053: case 's': ! 1054: p=in_line+2; ! 1055: tp=p; ! 1056: while(*tp && *tp>' ') tp++; ! 1057: *tp=0; /* truncate address at first whitespace */ ! 1058: if(!strncasecmp(p,"ftp://",6)) ! 1059: break; ! 1060: SAFECOPY(server[s]->addr,p); ! 1061: p=tp+1; ! 1062: while(*p && *p<=' ') p++; /* desc follows whitepsace */ ! 1063: SAFECOPY(server[s]->desc,p); ! 1064: s++; ! 1065: break; ! 1066: } ! 1067: } ! 1068: memset(dist[r],0,sizeof(dist_t)); ! 1069: uifc.pop(NULL); ! 1070: if(list>=0) ! 1071: close(list); ! 1072: if(r<1) ! 1073: return(NULL); ! 1074: return(dist); ! 1075: } ! 1076: ! 1077: int choose_dist(char **opts) ! 1078: { ! 1079: int i; ! 1080: static int dist_dflt=0; ! 1081: ! 1082: uifc.helpbuf= "`Distribution List:`\n" ! 1083: "\nToDo: Add help."; ! 1084: ! 1085: i=uifc.list(WIN_MID|WIN_ACT,0,0,0,&dist_dflt,0 ! 1086: ,"Select Distribution",opts); ! 1087: return(i); ! 1088: } ! 1089: ! 1090: int choose_server(char **opts) ! 1091: { ! 1092: int i; ! 1093: static int srvr_dflt=0; ! 1094: ! 1095: uifc.helpbuf= "`Server List:`\n" ! 1096: "\nToDo: Add help."; ! 1097: i=uifc.list(WIN_MID|WIN_ACT,0,0,0,&srvr_dflt,0 ! 1098: ,"Select Server",opts); ! 1099: return(i); ! 1100: ! 1101: } ! 1102: /* End of SBBSINST.C */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.