|
|
1.1 root 1: /* sbbsinst.c */
2:
3: /* Synchronet installation utility */
4:
5: /* $Id: sbbsinst.c,v 1.91 2004/11/20 18:32:10 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 2003 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/utsname.h>
39: #include <stdio.h>
40: #include <stdlib.h>
41: #include <string.h>
42:
43: /* XPDEV */
44: #include "gen_defs.h"
45:
46: #define __COLORS
47: #include "ciolib.h"
48: #include "uifc.h"
49: #include "sbbs.h"
50: #include "httpio.h"
51:
52: /***************/
53: /* Definitions */
54: /***************/
55: #define DEFAULT_CVSROOT ":pserver:[email protected]:/cvsroot/sbbs"
56: #define DEFAULT_DISTFILE "sbbs_src.tgz"
57: #define DEFAULT_LIBFILE "lib-%s.tgz" /* MUST HAVE ONE %s for system type (os-machine or just os) */
58: #define DEFAULT_SYSTYPE "unix" /* If no other system type available, use this one */
59: #define MAX_DISTRIBUTIONS 50
60: #define MAX_DIST_FILES 10
61: #define MAX_SERVERS 100
62: #define MAX_FILELEN 32
63: #define MAKE_ERROR "make failure.\n"
64: #if defined(__linux__)
65: #define MAKE "make"
66: #else
67: #define MAKE "gmake"
68: #endif
69:
70: char *distlists[]={
71: "http://www.synchro.net/sbbsdist.lst"
72: ,"http://rob.synchro.net/sbbsdist.lst"
73: ,"http://cvs.synchro.net/sbbsdist.lst"
74: ,"http://bbs.synchro.net/sbbsdist.lst"
75: ,"http://freebsd.synchro.net/sbbsdist.lst"
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:
108: struct {
109: char install_path[256];
110: BOOL usebcc;
111: char cflags[256];
112: BOOL debug;
113: BOOL symlink;
114: BOOL cvs;
115: char cvstag[256];
116: char cvsroot[256];
117: char make_cmdline[128];
118: char sys_desc[1024];
119: struct utsname name;
120: char sbbsuser[9]; /* Historical UName limit of 8 chars */
121: char sbbsgroup[17]; /* Can't find historical limit for group names */
122: BOOL useX;
123: } params; /* Build parameters */
124:
125: #define MAKEFILE "/tmp/SBBSmakefile"
126:
127: #define CVSCOMMAND "cvs "
128:
129: char **opt;
130: char tmp[256];
131: char error[256];
132: char cflags[MAX_PATH+1];
133: char cvsroot[MAX_PATH+1];
134: char distlist_rev[128]="Unspecified";
135: char revision[16];
136:
137: int backup_level=5;
138: BOOL keep_makefile=FALSE;
139: BOOL http_distlist=TRUE;
140: BOOL http_verbose=FALSE;
141:
142: /**************/
143: /* Prototypes */
144: /**************/
145: void install_sbbs(dist_t *, struct server_ent_t *);
146: dist_t **get_distlist(void);
147: int choose_dist(char **opts);
148: int choose_server(char **opts);
149:
150: int filereadline(int sock, char *buf, size_t length, char *error)
151: {
152: char ch;
153: int i;
154:
155: for(i=0;1;) {
156: if(read(sock, &ch,1)!=1) {
157: if(error != NULL)
158: strcpy(error,"Error Reading File");
159: return(-1);
160: }
161:
162: if(ch=='\n')
163: break;
164:
165: if(i<length)
166: buf[i++]=ch;
167: }
168:
169: /* Terminate at length if longer */
170: if(i>length)
171: i=length;
172:
173: if(i>0 && buf[i-1]=='\r')
174: buf[--i]=0;
175: else
176: buf[i]=0;
177:
178: return(i);
179: }
180:
181: void bail(int code)
182: {
183: if(code) {
184: puts("\nHit a key...");
185: getch();
186: }
187: uifc.bail();
188:
189: exit(code);
190: }
191:
192: void allocfail(uint size)
193: {
194: printf("\7Error allocating %u bytes of memory.\n",size);
195: bail(1);
196: }
197:
198: int main(int argc, char **argv)
199: {
200: char** mopt;
201: char* p;
202: int i=0;
203: int main_dflt=0;
204: char str[129];
205: BOOL door_mode=FALSE;
206: dist_t **distlist;
207: int dist=0;
208: int server=0;
209: int ciolib_mode=CIOLIB_MODE_AUTO;
210:
211: /************/
212: /* Defaults */
213: /************/
214: SAFECOPY(params.install_path,"/usr/local/sbbs");
215: SAFECOPY(params.make_cmdline,MAKE " install -f install/GNUmakefile");
216: params.usebcc=FALSE;
217: SAFECOPY(params.cflags,"");
218: params.debug=FALSE;
219: params.symlink=TRUE;
220: params.cvs=TRUE;
221: SAFECOPY(params.cvstag,"HEAD");
222: SAFECOPY(params.cvsroot,DEFAULT_CVSROOT);
223: if((p=getenv("USER"))!=NULL)
224: SAFECOPY(params.sbbsuser,p);
225: if((p=getenv("GROUP"))!=NULL)
226: SAFECOPY(params.sbbsgroup,p);
227: params.useX=FALSE;
228:
229: sscanf("$Revision: 1.91 $", "%*s %s", revision);
230:
231: printf("\nSynchronet Installation %s-%s Copyright 2003 "
232: "Rob Swindell\n",revision,PLATFORM_DESC);
233:
234: memset(&uifc,0,sizeof(uifc));
235:
236: uifc.esc_delay=25;
237:
238: for(i=1;i<argc;i++) {
239: if(argv[i][0]=='-'
240: #ifndef __unix__
241: || argv[i][0]=='/'
242: #endif
243: )
244: switch(toupper(argv[i][1])) {
245: case 'C':
246: uifc.mode|=UIFC_COLOR;
247: break;
248: case 'D':
249: printf("NOTICE: The -d option is depreciated, use -id instead\r\n");
250: SLEEP(2000);
251: door_mode=TRUE;
252: break;
253: case 'L':
254: uifc.scrn_len=atoi(argv[i]+2);
255: break;
256: case 'E':
257: uifc.esc_delay=atoi(argv[i]+2);
258: break;
259: case 'F':
260: case 'H':
261: http_verbose=TRUE;
262: break;
263: case 'N':
264: http_distlist=FALSE;
265: break;
266: case 'I':
267: switch(toupper(argv[i][2])) {
268: case 'A':
269: ciolib_mode=CIOLIB_MODE_ANSI;
270: break;
271: case 'C':
272: ciolib_mode=CIOLIB_MODE_CURSES;
273: break;
274: case 0:
275: printf("NOTICE: The -i option is depreciated, use -if instead\r\n");
276: SLEEP(2000);
277: case 'F':
278: ciolib_mode=CIOLIB_MODE_CURSES_IBM;
279: break;
280: case 'X':
281: ciolib_mode=CIOLIB_MODE_X;
282: break;
283: case 'W':
284: ciolib_mode=CIOLIB_MODE_CONIO;
285: break;
286: case 'D':
287: door_mode=TRUE;
288: break;
289: default:
290: goto USAGE;
291: }
292: break;
293: case 'V':
294: textmode(atoi(argv[i]+2));
295: break;
296: default:
297: USAGE:
298: printf("\nusage: %s [ctrl_dir] [options]"
299: "\n\noptions:\n\n"
300: "-n = do not HTTP-download distribution list\n"
301: "-h = run in HTTP-verbose (debug) mode\n"
302: "-c = force color mode\n"
303: #ifdef USE_CURSES
304: "-e# = set escape delay to #msec\n"
305: #endif
306: "-iX = set interface mode to X (default=auto) where X is one of:\r\n"
307: #ifdef __unix__
308: " X = X11 mode\r\n"
309: " C = Curses mode\r\n"
310: " F = Curses mode with forced IBM charset\r\n"
311: #else
312: " W = Win32 native mode\r\n"
313: #endif
314: " A = ANSI mode\r\n"
315: "-v# = set video mode to #\n"
316: "-l# = set screen lines to #\n"
317: ,argv[0]
318: );
319: exit(0);
320: }
321: }
322:
323: uifc.size=sizeof(uifc);
324: if(!door_mode) {
325: i=initciolib(ciolib_mode);
326: if(i!=0) {
327: printf("ciolib library init returned error %d\n",i);
328: exit(1);
329: }
330: i=uifcini32(&uifc); /* curses/conio/X/ANSI */
331: }
332: else
333: i=uifcinix(&uifc); /* stdio */
334: if(i!=0) {
335: printf("uifc library init returned error %d\n",i);
336: exit(1);
337: }
338:
339: if(uname(¶ms.name)<0) {
340: SAFECOPY(params.name.machine,"Unknown");
341: SAFECOPY(params.name.sysname,params.name.machine);
342: }
343: sprintf(params.sys_desc,"%s-%s",params.name.sysname,params.name.machine);
344:
345: distlist=get_distlist();
346:
347: if(distlist==NULL) {
348: printf("No installation files or distribution list present!\n");
349: exit(1);
350: }
351:
352: if((opt=(char **)MALLOC(sizeof(char *)*(MAX_OPTS+1)))==NULL)
353: allocfail(sizeof(char *)*(MAX_OPTS+1));
354: for(i=0;i<(MAX_OPTS+1);i++)
355: if((opt[i]=(char *)MALLOC(MAX_OPLN))==NULL)
356: allocfail(MAX_OPLN);
357:
358: if((mopt=(char **)MALLOC(sizeof(char *)*MAX_OPTS))==NULL)
359: allocfail(sizeof(char *)*MAX_OPTS);
360: for(i=0;i<MAX_OPTS;i++)
361: if((mopt[i]=(char *)MALLOC(MAX_OPLN))==NULL)
362: allocfail(MAX_OPLN);
363:
364: sprintf(str,"Synchronet Installation %s-%s",revision,PLATFORM_DESC);
365: if(uifc.scrn(str)) {
366: printf(" USCRN (len=%d) failed!\n",uifc.scrn_len+1);
367: bail(1);
368: }
369:
370: while(1) {
371: i=0;
372: sprintf(mopt[i++],"%-27.27s%s","Distribution",distlist[dist]->version);
373: sprintf(mopt[i++],"%-27.27s%s","Server"
374: ,(distlist[dist]->type==LOCAL_FILE?"Local Files":distlist[dist]->servers[server]->desc));
375: sprintf(mopt[i++],"%-27.27s%s","System Type",params.sys_desc);
376: sprintf(mopt[i++],"%-27.27s%s","Install Path",params.install_path);
377: sprintf(mopt[i++],"%-27.27s%s","Compiler",params.usebcc?"Borland":"GNU");
378: sprintf(mopt[i++],"%-27.27s%s","Compiler Flags",params.cflags);
379: sprintf(mopt[i++],"%-27.27s%s","Debug Build",params.debug?"Yes":"No");
380: sprintf(mopt[i++],"%-27.27s%s","Symlink Binaries",params.symlink?"Yes":"No");
381: sprintf(mopt[i++],"%-27.27s%s","Make Command-line",params.make_cmdline);
382: sprintf(mopt[i++],"%-27.27s%s","File Owner",params.sbbsuser);
383: sprintf(mopt[i++],"%-27.27s%s","File Group",params.sbbsgroup);
384: #if 0 /* this won't work until we get the FTLK source in CVS */
385: sprintf(mopt[i++],"%-27.27s%s","Include X/FLTK Support",params.useX?"Yes":"No");
386: #endif
387: sprintf(mopt[i++],"%-27.27s","Start Installation...");
388: mopt[i][0]=0;
389:
390: sprintf(str,"Synchronet Installation - Distribution List %s",distlist_rev);
391: uifc.helpbuf= "`Synchronet Installation:`\n"
392: "\nToDo: Add help.";
393: switch(uifc.list(WIN_ESC|WIN_MID|WIN_ACT|WIN_ORG,0,0,70,&main_dflt,0
394: ,str,mopt)) {
395: case 0:
396: i=choose_dist((char **)distlist);
397: if(i>=0) {
398: server=0;
399: dist=i;
400: }
401: break;
402: case 1:
403: if(distlist[dist]->type != LOCAL_FILE) {
404: i=choose_server((char **)distlist[dist]->servers);
405: if(i>=0)
406: server=i;
407: }
408: break;
409: case 2:
410: uifc.helpbuf= "`System Type`\n"
411: "\nToDo: Add help.";
412: uifc.input(WIN_MID,0,0,"System Type",params.sys_desc,40,K_EDIT);
413: break;
414: case 3:
415: uifc.helpbuf= "`Install Path`\n"
416: "\n"
417: "\nPath to install the Synchronet BBS system into."
418: "\nSome common paths:"
419: "\n /sbbs"
420: "\n /usr/local/sbbs"
421: "\n /opt/sbbs"
422: "\n /home/bbs/sbbs";
423: uifc.input(WIN_MID,0,0,"",params.install_path,50,K_EDIT);
424: break;
425: case 4:
426: strcpy(opt[0],"Borland");
427: strcpy(opt[1],"GNU");
428: opt[2][0]=0;
429: i=params.usebcc?0:1;
430: uifc.helpbuf= "`Which Compiler`\n"
431: "\nToDo: Add help.";
432: i=uifc.list(WIN_MID|WIN_SAV,0,0,0,&i,0
433: ,"Compiler",opt);
434: if(!i)
435: params.usebcc=TRUE;
436: else if(i==1)
437: params.usebcc=FALSE;
438: i=0;
439: break;
440: case 5:
441: uifc.helpbuf= "`Compiler Flags`\n"
442: "\nToDo: Add help.";
443: uifc.input(WIN_MID,0,0,"Additional Compiler Flags",params.cflags,40,K_EDIT);
444: break;
445: case 6:
446: strcpy(opt[0],"Yes");
447: strcpy(opt[1],"No");
448: opt[2][0]=0;
449: i=params.debug?0:1;
450: uifc.helpbuf= "`Debug Build`\n"
451: "\nToDo: Add help.";
452: i=uifc.list(WIN_MID|WIN_SAV,0,0,0,&i,0
453: ,"Build a Debug Version",opt);
454: if(!i)
455: params.debug=TRUE;
456: else if(i==1)
457: params.debug=FALSE;
458: i=0;
459: break;
460: case 7:
461: strcpy(opt[0],"Yes");
462: strcpy(opt[1],"No");
463: opt[2][0]=0;
464: i=params.symlink?0:1;
465: uifc.helpbuf= "`Symlink Binaries:`\n"
466: "\n"
467: "\nShould the installer create symlinks to the binaries or copy them from"
468: "\nthe compiled location?";
469: i=uifc.list(WIN_MID|WIN_SAV,0,0,0,&i,0
470: ,"Symlink Binaries",opt);
471: if(!i)
472: params.symlink=TRUE;
473: else if(i==1)
474: params.symlink=FALSE;
475: i=0;
476: break;
477: case 8:
478: uifc.helpbuf= "`Make Command-line`\n"
479: "\n";
480: uifc.input(WIN_MID,0,0,"",params.make_cmdline,65,K_EDIT);
481: break;
482: case 9:
483: uifc.helpbuf= "`File Owner`\n"
484: "\n";
485: uifc.input(WIN_MID,0,0,"",params.sbbsuser,8,K_EDIT);
486: break;
487: case 10:
488: uifc.helpbuf= "`File Group`\n"
489: "\n";
490: uifc.input(WIN_MID,0,0,"",params.sbbsgroup,32,K_EDIT);
491: break;
492: #if 0
493: case 11:
494: strcpy(opt[0],"Yes");
495: strcpy(opt[1],"No");
496: opt[2][0]=0;
497: i=params.useX?0:1;
498: uifc.helpbuf= "`Include X Support`\n"
499: "\nToDo: Add help.";
500: i=uifc.list(WIN_MID|WIN_SAV,0,0,0,&i,0
501: ,"Build GUI Versions of scfg and echocfg",opt);
502: if(!i)
503: params.useX=TRUE;
504: else if(i==1)
505: params.useX=FALSE;
506: i=0;
507: break;
508: #endif
509: case 11:
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: printf("%s\n",cmd);
534: fflush(stdout);
535: return(system(cmd));
536: }
537:
538: /* Some jiggery-pokery here to avoid having to enter the CVS password */
539: /* fprintf(makefile,"\tif(grep '%s' -q ~/.cvspass) then echo \"%s A\" >> ~/.cvspass; fi\n",
540: * params.cvsroot,params.cvsroot);
541: *
542: * Actually, it looks like you don't NEED to login if the password is blank... huh.
543: */
544:
545: void install_sbbs(dist_t *dist,struct server_ent_t *server) {
546: char cmd[MAX_PATH+1];
547: char str[1024];
548: char fname[MAX_PATH+1];
549: char dstfname[MAX_PATH+1];
550: char sbbsdir[9+MAX_PATH];
551: char cvstag[7+MAX_PATH];
552: char buf[4096];
553: char url[MAX_PATH+1];
554: char path[MAX_PATH+1];
555: char sbbsuser[128];
556: char sbbsgroup[128];
557: int i;
558: int fout,ret1,ret2;
559: size_t flen;
560: long offset;
561: int remote;
562: char http_error[128];
563:
564: if(params.debug)
565: putenv("DEBUG=1");
566: else
567: putenv("RELEASE=1");
568:
569: if(params.symlink)
570: putenv("SYMLINK=1");
571:
572: sprintf(sbbsdir,"SBBSDIR=%s",params.install_path);
573: putenv(sbbsdir);
574: if(params.sbbsuser[0]) {
575: sprintf(sbbsuser,"SBBSUSER=%s",params.sbbsuser);
576: putenv(sbbsuser);
577: }
578: if(params.sbbsgroup[0]) {
579: sprintf(sbbsgroup,"SBBSGROUP=%s",params.sbbsgroup);
580: putenv(sbbsgroup);
581: }
582: if(params.useX==TRUE) {
583: putenv("MKFLAGS=USE_FLTK=1");
584: }
585:
586: if(params.usebcc)
587: putenv("bcc=1");
588:
589: sprintf(path,"%s",FULLPATH(str,"./",sizeof(str)));
590: if(mkdir(params.install_path,0777)&&errno!=EEXIST) {
591: sprintf(str,"Could not create install %s!",params.install_path);
592: uifc.msg(str);
593: bail(EXIT_FAILURE);
594: }
595: if(chdir(params.install_path)) {
596: sprintf(str,"Could not change to %s (%d)!",params.install_path,errno);
597: uifc.msg(str);
598: bail(EXIT_FAILURE);
599: }
600: uifc.bail();
601: switch (dist->type) {
602: case CVS_SERVER:
603: sprintf(cvstag,"CVSTAG=%s",dist->tag);
604: putenv(cvstag);
605: sprintf(cmd,"cvs -d %s co -r %s install",server->addr,dist->tag);
606: if(exec(cmd)) {
607: printf("Could not checkout install makefile.\n");
608: exit(EXIT_FAILURE);
609: }
610: sprintf(cmd,"%s %s",params.make_cmdline,dist->make_opts);
611: if(exec(cmd)) {
612: printf(MAKE_ERROR);
613: exit(EXIT_FAILURE);
614: }
615: break;
616: case DIST_SET:
617: for(i=0;dist->files[i][0];i++) {
618: sprintf(fname,dist->files[i],params.sys_desc);
619: SAFECOPY(dstfname,fname);
620: if((fout=open(fname,O_WRONLY|O_TRUNC|O_CREAT,S_IRUSR|S_IWUSR))<0) {
621: printf("Could not download distfile to %s (%d)\n",fname,errno);
622: exit(EXIT_FAILURE);
623: }
624: sprintf(url,"%s%s",server->addr,fname);
625: if((remote=http_get_fd(url,&flen,NULL))<0) {
626: /* retry without machine type in name */
627: SAFECOPY(str,fname);
628: sprintf(fname,dist->files[i],params.name.sysname);
629: sprintf(url,"%s%s",server->addr,fname);
630: if(stricmp(str,fname)==0 /* no change in name? */
631: || (remote=http_get_fd(url,&flen,NULL))<0) {
632: /* retry using default system-type for system name */
633: sprintf(fname,dist->files[i],DEFAULT_SYSTYPE);
634: if((remote=http_get_fd(url,&flen,http_error))<0) {
635: printf("Cannot get distribution file %s!\n",fname);
636: printf("%s\n- %s\n",url,http_error);
637: close(fout);
638: unlink(dstfname);
639: exit(EXIT_FAILURE);
640: }
641: }
642: }
643: printf("Downloading %s ",url);
644: offset=0;
645: while((ret1=read(remote,buf,sizeof(buf)))>0) {
646: ret2=write(fout,buf,ret1);
647: if(ret2!=ret1) {
648: printf("\n!ERROR %d writing to %s\n",errno,dstfname);
649: close(fout);
650: unlink(dstfname);
651: exit(EXIT_FAILURE);
652: }
653: offset+=ret2;
654: if(flen)
655: printf("\b\b\b\b\b\b\b\b\b\b%3lu%% ",(long)(((float)offset/(float)flen)*100.0));
656: else
657: printf("\b\b\b\b\b\b\b\b\b\b%10lu",offset);
658: fflush(stdout);
659: }
660: printf("\n");
661: fflush(stdout);
662: if(ret1<0) {
663: printf("!ERROR downloading %s\n",fname);
664: close(fout);
665: unlink(dstfname);
666: exit(EXIT_FAILURE);
667: }
668: close(fout);
669: sprintf(cmd,"gzip -dc %s | tar -xvf -",dstfname);
670: if(exec(cmd)) {
671: printf("Error extracting %s\n",dstfname);
672: unlink(dstfname);
673: exit(EXIT_FAILURE);
674: }
675: unlink(dstfname);
676: }
677: sprintf(cmd,"%s %s",params.make_cmdline,dist->make_opts);
678: if(exec(cmd)) {
679: printf(MAKE_ERROR);
680: exit(EXIT_FAILURE);
681: }
682: break;
683: case LOCAL_FILE:
684: for(i=0;dist->files[i][0];i++) {
685: sprintf(cmd,"gzip -dc %s/%s | tar -xvf -",path,dist->files[i]);
686: if(exec(cmd)) {
687: printf("Error extracting %s/%s\n",path,dist->files[i]);
688: exit(EXIT_FAILURE);
689: }
690: }
691: sprintf(cmd,"%s %s",params.make_cmdline,dist->make_opts);
692: if(exec(cmd)) {
693: printf(MAKE_ERROR);
694: exit(EXIT_FAILURE);
695: }
696: break;
697: }
698:
699: sprintf(cmd,"more -c %s/docs/sbbscon.txt",params.install_path);
700: exec(cmd);
701: printf("Synchronet has been successfully installed to:\n\t%s\n",params.install_path);
702: printf("Documentation files in:\n\t%s/docs\n",params.install_path);
703: printf("Configuration files in:\n\t%s/ctrl\n",params.install_path);
704: printf("Executable program files in:\n\t%s/exec\n",params.install_path);
705: exit(EXIT_SUCCESS);
706:
707: }
708:
709: dist_t **
710: get_distlist(void)
711: {
712: int i;
713: char in_line[256];
714: dist_t **dist;
715: char **file=NULL;
716: struct server_ent_t **server=NULL;
717: int r=0;
718: int f=0;
719: int s=0;
720: char* p;
721: char* tp;
722: int list=-1;
723: char sep[2]={'\t',0};
724: char str[1024];
725: char errors[sizeof(distlists)/sizeof(char*)][128];
726: int (*readline) (int sock, char *buf, size_t length, char *error)=NULL;
727:
728: memset(errors,0,sizeof(errors));
729: if((dist=(dist_t **)MALLOC(sizeof(void *)*MAX_DISTRIBUTIONS))==NULL)
730: allocfail(sizeof(void *)*MAX_DISTRIBUTIONS);
731: for(i=0;i<MAX_DISTRIBUTIONS;i++)
732: if((dist[i]=(void *)MALLOC(sizeof(dist_t)))==NULL)
733: allocfail(sizeof(dist_t));
734:
735: sprintf(str,DEFAULT_LIBFILE,params.sys_desc);
736: if(!fexistcase(str)) /* use lib-linux.tgz if lib-linux-i686.tgz doesn't exist */
737: sprintf(str,DEFAULT_LIBFILE,params.name.sysname);
738: if(!fexistcase(str)) /* use lib-unix.tgz if all else fails */
739: sprintf(str,DEFAULT_LIBFILE,DEFAULT_SYSTYPE);
740: if(fexist(DEFAULT_DISTFILE) && fexistcase(str)) {
741: if((file=(char **)MALLOC(sizeof(char *)*MAX_DIST_FILES))==NULL)
742: allocfail(sizeof(char *)*MAX_DIST_FILES);
743: for(i=0;i<MAX_DIST_FILES;i++)
744: if((file[i]=(char *)MALLOC(MAX_FILELEN))==NULL)
745: allocfail(MAX_FILELEN);
746: server=NULL;
747: f=0;
748: s=0;
749:
750: memset(dist[r],0,sizeof(dist_t));
751: sprintf(dist[r]->version,"%s (Local)",VERSION);
752: dist[r]->type=LOCAL_FILE;
753: dist[r]->servers=server;
754: dist[r]->files=file;
755: strcpy(dist[r]->make_opts,"NOCVS=1");
756: r++;
757: strcpy(file[f++],DEFAULT_DISTFILE);
758: strcpy(file[f++],str);
759: }
760:
761: if(http_distlist) {
762: uifc.pop("Getting distributions");
763: for(i=0;distlists[i]!=NULL;i++) {
764: if((list=http_get_fd(distlists[i],NULL,errors[i]))>=0) {
765: readline=sockreadline;
766: break;
767: }
768: }
769: }
770: if(list<0) {
771: if(http_distlist)
772: uifc.pop(NULL);
773: uifc.pop("Loading distlist");
774: if((list=open("./sbbsdist.lst",O_RDONLY))<0)
775: list=open("../sbbsdist.lst",O_RDONLY);
776: if(list>=0)
777: readline=filereadline;
778: }
779: if(list<0) {
780: uifc.bail();
781: printf("Cannot get distribution list!\n");
782: for(i=0;distlists[i]!=NULL;i++)
783: printf("%s\n- %s\n",distlists[i],errors[i]);
784: exit(EXIT_FAILURE);
785: }
786:
787: while(readline != NULL && list>=0 && (readline(list,in_line,sizeof(in_line),NULL)>=0)) {
788: i=strlen(in_line);
789: while(i>0 && in_line[i]<=' ')
790: in_line[i--]=0;
791:
792: if(in_line[0]=='D') {
793: strcpy(str,in_line);
794: sep[0]=' ';
795: p=strtok(str,sep);
796: p=strtok(NULL,sep);
797: if(strstr(p,params.sys_desc)==NULL)
798: break;
799: sep[0]='\n';
800: p=strtok(NULL,sep);
801: strcpy(in_line,p);
802: }
803:
804: switch(in_line[0]) {
805: case 'R': /* revision */
806: sscanf(in_line+2, "%*s %s", distlist_rev);
807: break;
808: case 'C':
809: if(file!=NULL)
810: file[f]="";
811: if(server!=NULL)
812: memset(server[s],0,sizeof(struct server_ent_t));
813:
814: file=NULL;
815:
816: if((server=(struct server_ent_t **)MALLOC(sizeof(void *)*MAX_SERVERS))==NULL)
817: allocfail(sizeof(struct server_ent_t *)*MAX_SERVERS);
818: for(i=0;i<MAX_SERVERS;i++)
819: if((server[i]=(struct server_ent_t *)MALLOC(sizeof(struct server_ent_t)))==NULL)
820: allocfail(64);
821: f=0;
822: s=0;
823:
824: memset(dist[r],0,sizeof(dist_t));
825: strcpy(dist[r]->version,in_line+2);
826: dist[r]->type=CVS_SERVER;
827: dist[r]->servers=server;
828: r++;
829: break;
830: case 'T':
831: if(file!=NULL)
832: file[f]="";
833: if(server!=NULL)
834: memset(server[s],0,sizeof(struct server_ent_t));
835:
836: if((file=(char **)MALLOC(sizeof(char *)*MAX_DIST_FILES))==NULL)
837: allocfail(sizeof(char *)*MAX_DIST_FILES);
838: for(i=0;i<MAX_DIST_FILES;i++)
839: if((file[i]=(char *)MALLOC(MAX_FILELEN))==NULL)
840: allocfail(MAX_FILELEN);
841:
842: if((server=(struct server_ent_t **)MALLOC(sizeof(struct server_ent_t *)*MAX_SERVERS))==NULL)
843: allocfail(sizeof(struct server_ent_t *)*MAX_SERVERS);
844: for(i=0;i<MAX_SERVERS;i++)
845: if((server[i]=(struct server_ent_t *)MALLOC(sizeof(struct server_ent_t)))==NULL)
846: allocfail(64);
847: f=0;
848: s=0;
849:
850: memset(dist[r],0,sizeof(dist_t));
851: strcpy(dist[r]->version,in_line+2);
852: dist[r]->type=DIST_SET;
853: dist[r]->servers=server;
854: dist[r]->files=file;
855: r++;
856: break;
857: case 'f':
858: strcpy(file[f++],in_line+2);
859: break;
860: case 't':
861: SAFECOPY(dist[r-1]->tag,in_line+2);
862: break;
863: case 'm':
864: SAFECOPY(dist[r-1]->make_opts,in_line+2);
865: break;
866: case 's':
867: p=in_line+2;
868: tp=p;
869: while(*tp && *tp>' ') tp++;
870: *tp=0; /* truncate address at first whitespace */
871: if(!strncasecmp(p,"ftp://",6))
872: break;
873: SAFECOPY(server[s]->addr,p);
874: p=tp+1;
875: while(*p && *p<=' ') p++; /* desc follows whitepsace */
876: SAFECOPY(server[s]->desc,p);
877: s++;
878: break;
879: }
880: }
881: memset(dist[r],0,sizeof(dist_t));
882: uifc.pop(NULL);
883: if(list>=0)
884: close(list);
885: if(r<1)
886: return(NULL);
887: return(dist);
888: }
889:
890: int choose_dist(char **opts)
891: {
892: int i;
893: static int dist_dflt=0;
894:
895: uifc.helpbuf= "`Distribution List:`\n"
896: "\nToDo: Add help.";
897:
898: i=uifc.list(WIN_MID|WIN_ACT,0,0,0,&dist_dflt,0
899: ,"Select Distribution",opts);
900: return(i);
901: }
902:
903: int choose_server(char **opts)
904: {
905: int i;
906: static int srvr_dflt=0;
907:
908: uifc.helpbuf= "`Server List:`\n"
909: "\nToDo: Add help.";
910: i=uifc.list(WIN_MID|WIN_ACT,0,0,0,&srvr_dflt,0
911: ,"Select Server",opts);
912: return(i);
913:
914: }
915: /* End of SBBSINST.C */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.