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