Annotation of sbbs/src/sbbs3/install/sbbsinst.c, revision 1.1.1.1

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(&params.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 */

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.