|
|
1.1 ! root 1: /* Upgrade Synchronet files from v3 to v4 */ ! 2: ! 3: /* $Id: v4upgrade.c,v 1.13 2005/10/16 22:45:10 rswindell Exp $ */ ! 4: ! 5: /**************************************************************************** ! 6: * @format.tab-size 4 (Plain Text/Source Code File Header) * ! 7: * @format.use-tabs true (see http://www.synchro.net/ptsc_hdr.html) * ! 8: * * ! 9: * Copyright 2005 Rob Swindell - http://www.synchro.net/copyright.html * ! 10: * * ! 11: * This program is free software; you can redistribute it and/or * ! 12: * modify it under the terms of the GNU General Public License * ! 13: * as published by the Free Software Foundation; either version 2 * ! 14: * of the License, or (at your option) any later version. * ! 15: * See the GNU General Public License for more details: gpl.txt or * ! 16: * http://www.fsf.org/copyleft/gpl.html * ! 17: * * ! 18: * Anonymous FTP access to the most recent released source is available at * ! 19: * ftp://vert.synchro.net, ftp://cvs.synchro.net and ftp://ftp.synchro.net * ! 20: * * ! 21: * Anonymous CVS access to the development source and modification history * ! 22: * is available at cvs.synchro.net:/cvsroot/sbbs, example: * ! 23: * cvs -d :pserver:[email protected]:/cvsroot/sbbs login * ! 24: * (just hit return, no password is necessary) * ! 25: * cvs -d :pserver:[email protected]:/cvsroot/sbbs checkout src * ! 26: * * ! 27: * For Synchronet coding style and modification guidelines, see * ! 28: * http://www.synchro.net/source.html * ! 29: * * ! 30: * You are encouraged to submit any modifications (preferably in Unix diff * ! 31: * format) via e-mail to [email protected] * ! 32: * * ! 33: * Note: If this box doesn't appear square, then you need to fix your tabs. * ! 34: ****************************************************************************/ ! 35: ! 36: #include "sbbs.h" ! 37: #include "sbbs4defs.h" ! 38: #include "ini_file.h" ! 39: #include "dat_file.h" ! 40: #include "datewrap.h" ! 41: ! 42: scfg_t scfg; ! 43: BOOL overwrite_existing_files=TRUE; ! 44: ini_style_t style = { 25, NULL, NULL, " = ", NULL }; ! 45: ! 46: BOOL overwrite(const char* path) ! 47: { ! 48: char str[128]; ! 49: ! 50: if(!overwrite_existing_files && fexist(path)) { ! 51: printf("\n%s already exists, overwrite? ",path); ! 52: fgets(str,sizeof(str),stdin); ! 53: if(toupper(*str)!='Y') ! 54: return(FALSE); ! 55: } ! 56: ! 57: return(TRUE); ! 58: } ! 59: ! 60: /****************************************************************************/ ! 61: /* Converts a date string in format MM/DD/YY into unix time format */ ! 62: /****************************************************************************/ ! 63: long DLLCALL dstrtodate(scfg_t* cfg, char *instr) ! 64: { ! 65: char* p; ! 66: char* day; ! 67: char str[16]; ! 68: struct tm tm; ! 69: ! 70: if(!instr[0] || !strncmp(instr,"00/00/00",8)) ! 71: return(0); ! 72: ! 73: if(isdigit(instr[0]) && isdigit(instr[1]) ! 74: && isdigit(instr[3]) && isdigit(instr[4]) ! 75: && isdigit(instr[6]) && isdigit(instr[7])) ! 76: p=instr; /* correctly formatted */ ! 77: else { ! 78: p=instr; /* incorrectly formatted */ ! 79: while(*p && isdigit(*p)) p++; ! 80: if(*p==0) ! 81: return(0); ! 82: p++; ! 83: day=p; ! 84: while(*p && isdigit(*p)) p++; ! 85: if(*p==0) ! 86: return(0); ! 87: p++; ! 88: sprintf(str,"%02u/%02u/%02u" ! 89: ,atoi(instr)%100,atoi(day)%100,atoi(p)%100); ! 90: p=str; ! 91: } ! 92: ! 93: memset(&tm,0,sizeof(tm)); ! 94: tm.tm_year=((p[6]&0xf)*10)+(p[7]&0xf); ! 95: if(cfg->sys_misc&SM_EURODATE) { ! 96: tm.tm_mon=((p[3]&0xf)*10)+(p[4]&0xf); ! 97: tm.tm_mday=((p[0]&0xf)*10)+(p[1]&0xf); } ! 98: else { ! 99: tm.tm_mon=((p[0]&0xf)*10)+(p[1]&0xf); ! 100: tm.tm_mday=((p[3]&0xf)*10)+(p[4]&0xf); } ! 101: ! 102: return(((tm.tm_year+1900)*10000)+(tm.tm_mon*100)+tm.tm_mday); ! 103: } ! 104: ! 105: ! 106: BOOL upgrade_users(void) ! 107: { ! 108: char outpath[MAX_PATH+1]; ! 109: char rec[USER_REC_LEN+1]; ! 110: FILE* out; ! 111: int i,total; ! 112: int ret; ! 113: size_t len; ! 114: user_t user; ! 115: ! 116: printf("Upgrading user database... "); ! 117: ! 118: sprintf(outpath,"%suser/user.tab",scfg.data_dir); ! 119: if(!overwrite(outpath)) ! 120: return(TRUE); ! 121: if((out=fopen(outpath,"wb"))==NULL) { ! 122: perror(outpath); ! 123: return(FALSE); ! 124: } ! 125: ! 126: fprintf(out,"%-*.*s\r\n",USER_REC_LEN,USER_REC_LEN,tabLineCreator(user_dat_columns)); ! 127: ! 128: total=lastuser(&scfg); ! 129: for(i=1;i<=total;i++) { ! 130: printf("\b\b\b\b\b%5u",total-i); ! 131: memset(&user,0,sizeof(user)); ! 132: user.number=i; ! 133: if((ret=getuserdat(&scfg,&user))!=0) { ! 134: printf("\nError %d reading user.dat\n",ret); ! 135: return(FALSE); ! 136: } ! 137: /******************************************/ ! 138: /* personal info */ ! 139: len=sprintf(rec,"%s\t%s\t%s\t%s\t%s\t%s\t" ! 140: ,user.alias ! 141: ,user.name ! 142: ,user.handle ! 143: ,user.note ! 144: ,user.comp ! 145: ,user.comment ! 146: ); ! 147: /* some unused records for future expansion */ ! 148: len+=sprintf(rec+len,"\t\t\t\t"); ! 149: ! 150: /******************************************/ ! 151: /* very personal info */ ! 152: len+=sprintf(rec+len,"%s\t%s\t%s\t%s\t%s\t%s\t%lu\t%c\t%s\t" ! 153: ,user.netmail ! 154: ,user.address ! 155: ,user.location ! 156: ,user.zipcode ! 157: ,user.pass ! 158: ,user.phone ! 159: ,dstrtodate(&scfg,user.birth) ! 160: ,user.sex ! 161: ,user.modem ! 162: ); ! 163: /* some unused records for future expansion */ ! 164: len+=sprintf(rec+len,"\t\t\t\t"); ! 165: ! 166: /******************************************/ ! 167: /* date/times */ ! 168: len+=sprintf(rec+len,"%08lu%06u\t%08lu%06u\t%08lu%06u\t%08lu%06u\t%08lu%06u\t%08lu%06u\t" ! 169: ,time_to_isoDate(user.laston) ! 170: ,time_to_isoTime(user.laston) ! 171: ,time_to_isoDate(user.firston) ! 172: ,time_to_isoTime(user.firston) ! 173: ,time_to_isoDate(user.expire) ! 174: ,time_to_isoTime(user.expire) ! 175: ,time_to_isoDate(user.pwmod) ! 176: ,time_to_isoTime(user.pwmod) ! 177: ,time_to_isoDate(user.ns_time) ! 178: ,time_to_isoTime(user.ns_time) ! 179: ,time_to_isoDate(user.logontime) ! 180: ,time_to_isoTime(user.logontime) ! 181: ); ! 182: /* some unused records for future expansion */ ! 183: len+=sprintf(rec+len,"\t\t\t\t"); ! 184: ! 185: /******************************************/ ! 186: /* counting stats */ ! 187: len+=sprintf(rec+len,"%u\t%u\t%u\t%u\t%u\t%u\t%u\t%u\t%u\t%u\t%u\t" ! 188: ,user.logons ! 189: ,user.ltoday ! 190: ,user.timeon ! 191: ,user.textra ! 192: ,user.ttoday ! 193: ,user.tlast ! 194: ,user.posts ! 195: ,user.emails ! 196: ,user.fbacks ! 197: ,user.etoday ! 198: ,user.ptoday ! 199: ); ! 200: /* some unused records for future expansion */ ! 201: len+=sprintf(rec+len,"\t\t\t\t"); ! 202: ! 203: /******************************************/ ! 204: /* file xfer stats, credits, minutes */ ! 205: len+=sprintf(rec+len,"%u\t%u\t%u\t%u\t%u\t%u\t%u\t" ! 206: ,user.ulb ! 207: ,user.uls ! 208: ,user.dlb ! 209: ,user.dls ! 210: ,user.cdt ! 211: ,user.freecdt ! 212: ,user.min ! 213: ); ! 214: /* some unused records for future expansion */ ! 215: len+=sprintf(rec+len,"\t\t\t\t"); ! 216: ! 217: /******************************************/ ! 218: /* security */ ! 219: len+=sprintf(rec+len,"%u\t%lx\t%lx\t%lx\t%lx\t%lx\t%lx\t" ! 220: ,user.level ! 221: ,user.flags1 ! 222: ,user.flags2 ! 223: ,user.flags3 ! 224: ,user.flags4 ! 225: ,user.exempt ! 226: ,user.rest ! 227: ); ! 228: /* some unused records for future expansion */ ! 229: len+=sprintf(rec+len,"\t\t\t\t"); ! 230: ! 231: /******************************************/ ! 232: /* settings (bit-fields) */ ! 233: len+=sprintf(rec+len,"%lx\t%lx\t%lx\t" ! 234: ,user.misc ! 235: ,user.qwk ! 236: ,user.chat ! 237: ); ! 238: /* some unused records for future expansion */ ! 239: len+=sprintf(rec+len,"\t\t\t\t"); ! 240: ! 241: /******************************************/ ! 242: /* settings (strings and numbers) */ ! 243: len+=sprintf(rec+len,"%u\t%c\t%s\t%s\t%s\t%s\t%s\t%s\t" ! 244: ,user.rows ! 245: ,user.prot ! 246: ,user.xedit ? scfg.xedit[user.xedit]->code : "" ! 247: ,scfg.shell[user.shell]->code ! 248: ,user.tmpext ! 249: ,user.cursub ! 250: ,user.curdir ! 251: ,user.curxtrn ! 252: ); ! 253: /* Message disabled. Why? ToDo */ ! 254: /* printf("reclen=%u\n",len); */ ! 255: if((ret=fprintf(out,"%-*.*s\r\n",USER_REC_LEN,USER_REC_LEN,rec))!=USER_REC_LINE_LEN) { ! 256: printf("!Error %d (errno: %d) writing %u bytes to user.tab\n" ! 257: ,ret, errno, USER_REC_LINE_LEN); ! 258: return(FALSE); ! 259: } ! 260: } ! 261: fclose(out); ! 262: ! 263: printf("\n\tdata/user/user.dat -> %s (%u users)\n", outpath,total); ! 264: ! 265: return(TRUE); ! 266: } ! 267: ! 268: typedef struct { ! 269: time_t time; ! 270: ulong ltoday; ! 271: ulong ttoday; ! 272: ulong uls; ! 273: ulong ulb; ! 274: ulong dls; ! 275: ulong dlb; ! 276: ulong ptoday; ! 277: ulong etoday; ! 278: ulong ftoday; ! 279: } csts_t; ! 280: ! 281: BOOL upgrade_stats(void) ! 282: { ! 283: char inpath[MAX_PATH+1]; ! 284: char outpath[MAX_PATH+1]; ! 285: BOOL success; ! 286: ulong count; ! 287: time_t t; ! 288: stats_t stats; ! 289: FILE* in; ! 290: FILE* out; ! 291: csts_t csts; ! 292: str_list_t list; ! 293: ! 294: printf("Upgrading statistics data...\n"); ! 295: ! 296: sprintf(inpath,"%sdsts.dab",scfg.ctrl_dir); ! 297: printf("\t%s ",inpath); ! 298: if((in=fopen(inpath,"rb"))==NULL) { ! 299: perror(inpath); ! 300: return(FALSE); ! 301: } ! 302: fread(&t,sizeof(t),1,in); ! 303: fread(&stats,sizeof(stats),1,in); ! 304: fclose(in); ! 305: ! 306: sprintf(outpath,"%sstats.dat",scfg.ctrl_dir); ! 307: if(!overwrite(outpath)) ! 308: return(TRUE); ! 309: if((out=fopen(outpath,"w"))==NULL) { ! 310: perror(outpath); ! 311: return(FALSE); ! 312: } ! 313: ! 314: if((list = strListInit())==NULL) { ! 315: printf("!malloc failure\n"); ! 316: return(FALSE); ! 317: } ! 318: ! 319: iniSetDateTime(&list, ROOT_SECTION ,"TimeStamp" ,TRUE, t ,NULL); ! 320: iniSetInteger(&list, ROOT_SECTION ,"Logons" ,stats.logons ,NULL); ! 321: iniSetInteger(&list, ROOT_SECTION ,"LogonsToday" ,stats.ltoday ,NULL); ! 322: iniSetInteger(&list, ROOT_SECTION ,"Timeon" ,stats.timeon ,NULL); ! 323: iniSetInteger(&list, ROOT_SECTION ,"TimeonToday" ,stats.ttoday ,NULL); ! 324: iniSetInteger(&list, ROOT_SECTION ,"Uploads" ,stats.uls ,NULL); ! 325: iniSetLongInt(&list, ROOT_SECTION ,"UploadBytes" ,stats.ulb ,NULL); ! 326: iniSetInteger(&list, ROOT_SECTION ,"Downloads" ,stats.dls ,NULL); ! 327: iniSetLongInt(&list, ROOT_SECTION ,"DownloadBytes",stats.dlb ,NULL); ! 328: iniSetInteger(&list, ROOT_SECTION ,"PostsToday" ,stats.ptoday ,NULL); ! 329: iniSetInteger(&list, ROOT_SECTION ,"EmailToday" ,stats.etoday ,NULL); ! 330: iniSetInteger(&list, ROOT_SECTION ,"FeedbackToday",stats.ftoday ,NULL); ! 331: iniSetInteger(&list, ROOT_SECTION ,"NewUsersToday",stats.nusers ,NULL); ! 332: ! 333: success=iniWriteFile(out, list); ! 334: ! 335: fclose(out); ! 336: strListFree(&list); ! 337: printf("-> %s\n", outpath); ! 338: ! 339: if(!success) { ! 340: printf("!iniWriteFile failure\n"); ! 341: return(FALSE); ! 342: } ! 343: ! 344: sprintf(inpath,"%scsts.dab",scfg.ctrl_dir); ! 345: printf("\t%s ",inpath); ! 346: if((in=fopen(inpath,"rb"))==NULL) { ! 347: perror(inpath); ! 348: return(FALSE); ! 349: } ! 350: ! 351: sprintf(outpath,"%sstats.tab",scfg.ctrl_dir); ! 352: if(!overwrite(outpath)) ! 353: return(TRUE); ! 354: if((out=fopen(outpath,"w"))==NULL) { ! 355: perror(outpath); ! 356: return(FALSE); ! 357: } ! 358: #if 0 ! 359: fprintf(out,"Time Stamp\tLogons\tTimeon\tUploaded Files\tUploaded Bytes\t" ! 360: "Downloaded Files\tDownloaded Bytes\tPosts\tEmail Sent\tFeedback Sent\r\n"); ! 361: #else ! 362: fprintf(out,"%s\n",tabLineCreator(stats_dat_columns)); ! 363: #endif ! 364: ! 365: count=0; ! 366: while(!feof(in)) { ! 367: if(fread(&csts,1,sizeof(csts),in)!=sizeof(csts)) ! 368: break; ! 369: fprintf(out,"%lu\t%lu\t%lu\t%lu\t%lu\t%lu\t%lu\t%lu\t%lu\t%lu\t\n" ! 370: ,time_to_isoDate(csts.time) ! 371: ,csts.ltoday ! 372: ,csts.ttoday ! 373: ,csts.uls ! 374: ,csts.ulb ! 375: ,csts.dls ! 376: ,csts.dlb ! 377: ,csts.ptoday ! 378: ,csts.etoday ! 379: ,csts.ftoday ! 380: ); ! 381: count++; ! 382: } ! 383: fclose(in); ! 384: fclose(out); ! 385: printf("-> %s (%u days)\n", outpath, count); ! 386: ! 387: return(success); ! 388: } ! 389: ! 390: BOOL upgrade_event_data(void) ! 391: { ! 392: char inpath[MAX_PATH+1]; ! 393: char outpath[MAX_PATH+1]; ! 394: BOOL success; ! 395: FILE* in; ! 396: FILE* out; ! 397: size_t i; ! 398: time_t t; ! 399: str_list_t list; ! 400: ! 401: printf("Upgrading event data...\n"); ! 402: ! 403: sprintf(outpath,"%sevent.dat",scfg.ctrl_dir); ! 404: if(!overwrite(outpath)) ! 405: return(TRUE); ! 406: if((out=fopen(outpath,"w"))==NULL) { ! 407: perror(outpath); ! 408: return(FALSE); ! 409: } ! 410: ! 411: if((list = strListInit())==NULL) { ! 412: printf("!malloc failure\n"); ! 413: return(FALSE); ! 414: } ! 415: ! 416: /* Read TIME.DAB */ ! 417: sprintf(inpath,"%stime.dab",scfg.ctrl_dir); ! 418: printf("\t%s ",inpath); ! 419: if((in=fopen(inpath,"rb"))==NULL) { ! 420: perror("open failure"); ! 421: return(FALSE); ! 422: } ! 423: for(i=0;i<scfg.total_events;i++) { ! 424: t=0; ! 425: fread(&t,1,sizeof(t),in); ! 426: iniSetHexInt(&list, "Events", scfg.event[i]->code, t, NULL); ! 427: } ! 428: t=0; ! 429: fread(&t,1,sizeof(t),in); ! 430: iniSetHexInt(&list,ROOT_SECTION,"QWKPrePack",t,NULL); ! 431: fclose(in); ! 432: ! 433: printf("-> %s (%u timed events)\n", outpath, i); ! 434: ! 435: /* Read QNET.DAB */ ! 436: sprintf(inpath,"%sqnet.dab",scfg.ctrl_dir); ! 437: printf("\t%s ",inpath); ! 438: i=0; ! 439: if((in=fopen(inpath,"rb"))==NULL) ! 440: perror("open failure"); ! 441: else { ! 442: for(i=0;i<scfg.total_qhubs;i++) { ! 443: t=0; ! 444: fread(&t,1,sizeof(t),in); ! 445: iniSetHexInt(&list,"QWKNetworkHubs",scfg.qhub[i]->id,t,NULL); ! 446: } ! 447: fclose(in); ! 448: } ! 449: printf("-> %s (%u QWKnet hubs)\n", outpath, i); ! 450: ! 451: success=iniWriteFile(out, list); ! 452: ! 453: fclose(out); ! 454: strListFree(&list); ! 455: ! 456: if(!success) { ! 457: printf("!iniWriteFile failure\n"); ! 458: return(FALSE); ! 459: } ! 460: ! 461: return(success); ! 462: } ! 463: ! 464: BOOL upgrade_ip_filters(void) ! 465: { ! 466: char inpath[MAX_PATH+1]; ! 467: char outpath[MAX_PATH+1]; ! 468: char msgpath[MAX_PATH+1]; ! 469: char str[INI_MAX_VALUE_LEN]; ! 470: char estr[INI_MAX_VALUE_LEN]; ! 471: char* p; ! 472: FILE* in; ! 473: FILE* out; ! 474: BOOL success; ! 475: size_t i; ! 476: size_t total; ! 477: str_list_t inlist; ! 478: str_list_t outlist; ! 479: ! 480: style.section_separator = NULL; ! 481: iniSetDefaultStyle(style); ! 482: ! 483: printf("Upgrading IP Address filters...\n"); ! 484: ! 485: sprintf(outpath,"%sip-filter.ini",scfg.ctrl_dir); ! 486: if(!overwrite(outpath)) ! 487: return(TRUE); ! 488: if((out=fopen(outpath,"w"))==NULL) { ! 489: perror(outpath); ! 490: return(FALSE); ! 491: } ! 492: ! 493: if((outlist = strListInit())==NULL) { ! 494: printf("!malloc failure\n"); ! 495: return(FALSE); ! 496: } ! 497: ! 498: /* Read the message file (if present) */ ! 499: sprintf(msgpath,"%sbadip.msg",scfg.text_dir); ! 500: if(fexist(msgpath)) { ! 501: printf("\t%s ",msgpath); ! 502: ! 503: if((in=fopen(msgpath,"r"))==NULL) { ! 504: perror("open failure"); ! 505: return(FALSE); ! 506: } ! 507: ! 508: i=fread(str,1,INI_MAX_VALUE_LEN,in); ! 509: str[i]=0; ! 510: truncsp(str); ! 511: fclose(in); ! 512: ! 513: if(strlen(str)) { ! 514: c_escape_str(str,estr,sizeof(estr),/* ctrl_only? */TRUE); ! 515: iniSetString(&outlist,ROOT_SECTION,"Message",estr,NULL); ! 516: } ! 517: ! 518: printf("-> %s\n", outpath); ! 519: } ! 520: ! 521: sprintf(inpath,"%sip.can",scfg.text_dir); ! 522: printf("\t%s ",inpath); ! 523: if((in=fopen(inpath,"r"))==NULL) { ! 524: perror("open failure"); ! 525: return(FALSE); ! 526: } ! 527: ! 528: if((inlist = strListReadFile(in,NULL,4096))==NULL) { ! 529: printf("!failure reading %s\n",inpath); ! 530: return(FALSE); ! 531: } ! 532: ! 533: total=0; ! 534: for(i=0;inlist[i]!=NULL;i++) { ! 535: p=truncsp(inlist[i]); ! 536: SKIP_WHITESPACE(p); ! 537: if(*p==';') ! 538: strListPush(&outlist,p); ! 539: else if(*p) { ! 540: iniAppendSection(&outlist,p,NULL); ! 541: total++; ! 542: } ! 543: } ! 544: ! 545: printf("-> %s (%u IP Addresses)\n", outpath, total); ! 546: fclose(in); ! 547: strListFreeStrings(inlist); ! 548: ! 549: sprintf(inpath,"%sip-silent.can",scfg.text_dir); ! 550: printf("\t%s ",inpath); ! 551: if((in=fopen(inpath,"r"))==NULL) { ! 552: perror("open failure"); ! 553: return(FALSE); ! 554: } ! 555: ! 556: if((inlist = strListReadFile(in,NULL,4096))==NULL) { ! 557: printf("!failure reading %s\n",inpath); ! 558: return(FALSE); ! 559: } ! 560: ! 561: total=0; ! 562: for(i=0;inlist[i]!=NULL;i++) { ! 563: p=truncsp(inlist[i]); ! 564: SKIP_WHITESPACE(p); ! 565: if(*p==';') ! 566: strListPush(&outlist,p); ! 567: else if(*p) { ! 568: iniSetBool(&outlist,p,"Silent",TRUE,NULL); ! 569: total++; ! 570: } ! 571: } ! 572: ! 573: printf("-> %s (%u IP Addresses)\n", outpath, total); ! 574: fclose(in); ! 575: strListFree(&inlist); ! 576: ! 577: success=iniWriteFile(out, outlist); ! 578: ! 579: fclose(out); ! 580: ! 581: if(!success) { ! 582: printf("!iniWriteFile failure\n"); ! 583: return(FALSE); ! 584: } ! 585: ! 586: printf("\tFiltering %u total IP Addresses\n", iniGetSectionCount(outlist,NULL)); ! 587: ! 588: strListFree(&outlist); ! 589: ! 590: return(success); ! 591: } ! 592: ! 593: BOOL upgrade_filter(const char* desc, const char* inpath, const char* msgpath, const char* outpath) ! 594: { ! 595: char* p; ! 596: char str[INI_MAX_VALUE_LEN]; ! 597: char estr[INI_MAX_VALUE_LEN]; ! 598: FILE* in; ! 599: FILE* out; ! 600: BOOL success; ! 601: size_t i; ! 602: size_t total; ! 603: str_list_t inlist; ! 604: str_list_t outlist; ! 605: ! 606: style.section_separator = NULL; ! 607: iniSetDefaultStyle(style); ! 608: ! 609: printf("Upgrading %s filters...\n",desc); ! 610: ! 611: if(!overwrite(outpath)) ! 612: return(TRUE); ! 613: if((out=fopen(outpath,"w"))==NULL) { ! 614: perror(outpath); ! 615: return(FALSE); ! 616: } ! 617: ! 618: if((outlist = strListInit())==NULL) { ! 619: printf("!malloc failure\n"); ! 620: return(FALSE); ! 621: } ! 622: ! 623: /* Read the message file (if present) */ ! 624: if(msgpath!=NULL && fexist(msgpath)) { ! 625: printf("\t%s ",msgpath); ! 626: ! 627: if((in=fopen(msgpath,"r"))==NULL) { ! 628: perror("open failure"); ! 629: return(FALSE); ! 630: } ! 631: ! 632: i=fread(str,1,INI_MAX_VALUE_LEN,in); ! 633: str[i]=0; ! 634: truncsp(str); ! 635: fclose(in); ! 636: ! 637: if(strlen(str)) { ! 638: c_escape_str(str,estr,sizeof(estr),/* ctrl_only? */TRUE); ! 639: iniSetString(&outlist,ROOT_SECTION,"Message",estr,NULL); ! 640: } ! 641: ! 642: printf("-> %s\n", outpath); ! 643: } ! 644: ! 645: printf("\t%s ",inpath); ! 646: if((in=fopen(inpath,"r"))==NULL) { ! 647: perror("open failure"); ! 648: return(FALSE); ! 649: } ! 650: ! 651: if((inlist = strListReadFile(in,NULL,4096))==NULL) { ! 652: printf("!failure reading %s\n",inpath); ! 653: return(FALSE); ! 654: } ! 655: ! 656: total=0; ! 657: for(i=0;inlist[i]!=NULL;i++) { ! 658: p=truncsp(inlist[i]); ! 659: SKIP_WHITESPACE(p); ! 660: if(*p==';') ! 661: strListPush(&outlist,p); ! 662: else if(*p) { ! 663: iniAppendSection(&outlist,p,NULL); ! 664: total++; ! 665: } ! 666: } ! 667: ! 668: printf("-> %s (%u %ss)\n", outpath, total, desc); ! 669: fclose(in); ! 670: strListFree(&inlist); ! 671: ! 672: success=iniWriteFile(out, outlist); ! 673: ! 674: fclose(out); ! 675: ! 676: if(!success) { ! 677: printf("!iniWriteFile failure\n"); ! 678: return(FALSE); ! 679: } ! 680: ! 681: printf("\tFiltering %u total %ss\n", iniGetSectionCount(outlist,NULL),desc); ! 682: ! 683: strListFree(&outlist); ! 684: ! 685: return(success); ! 686: } ! 687: ! 688: BOOL upgrade_list(const char* desc, const char* infile, const char* outfile ! 689: ,BOOL section_list, const char* key) ! 690: { ! 691: char* p; ! 692: char* vp; ! 693: char inpath[MAX_PATH+1]; ! 694: char outpath[MAX_PATH+1]; ! 695: FILE* in; ! 696: FILE* out; ! 697: BOOL success; ! 698: size_t i; ! 699: size_t total; ! 700: str_list_t inlist; ! 701: str_list_t outlist; ! 702: ! 703: style.section_separator = (section_list && key==NULL) ? NULL : ""; ! 704: iniSetDefaultStyle(style); ! 705: ! 706: SAFEPRINTF2(inpath,"%s%s",scfg.ctrl_dir,infile); ! 707: SAFEPRINTF2(outpath,"%s%s",scfg.ctrl_dir,outfile); ! 708: ! 709: if(!fexistcase(inpath)) ! 710: return(TRUE); ! 711: ! 712: printf("Upgrading %s...\n",desc); ! 713: ! 714: if(!overwrite(outpath)) ! 715: return(TRUE); ! 716: if((out=fopen(outpath,"w"))==NULL) { ! 717: perror(outpath); ! 718: return(FALSE); ! 719: } ! 720: ! 721: if((outlist = strListInit())==NULL) { ! 722: printf("!malloc failure\n"); ! 723: return(FALSE); ! 724: } ! 725: printf("\t%s ",inpath); ! 726: if((in=fopen(inpath,"r"))==NULL) { ! 727: perror("open failure"); ! 728: return(FALSE); ! 729: } ! 730: ! 731: if((inlist = strListReadFile(in,NULL,4096))==NULL) { ! 732: printf("!failure reading %s\n",inpath); ! 733: return(FALSE); ! 734: } ! 735: ! 736: total=0; ! 737: for(i=0;inlist[i]!=NULL;i++) { ! 738: p=truncsp(inlist[i]); ! 739: SKIP_WHITESPACE(p); ! 740: if(*p==';') ! 741: strListPush(&outlist,p); ! 742: else if(*p) { ! 743: vp=NULL; ! 744: if((!section_list || key!=NULL) ! 745: && ((vp=strchr(p,' '))!=NULL || ((vp=strchr(p,'\t'))!=NULL))) { ! 746: *(vp++) = 0; ! 747: SKIP_WHITESPACE(vp); ! 748: } ! 749: if(section_list) { ! 750: iniAppendSection(&outlist,p,NULL); ! 751: if(vp!=NULL && *vp) ! 752: iniSetString(&outlist,p,key,vp,NULL); ! 753: } else ! 754: iniSetString(&outlist,ROOT_SECTION,p,vp,NULL); ! 755: total++; ! 756: } ! 757: } ! 758: ! 759: printf("-> %s (%u)\n", outpath, total); ! 760: fclose(in); ! 761: strListFree(&inlist); ! 762: ! 763: success=iniWriteFile(out, outlist); ! 764: ! 765: fclose(out); ! 766: ! 767: if(!success) { ! 768: printf("!iniWriteFile failure\n"); ! 769: return(FALSE); ! 770: } ! 771: ! 772: printf("\tWrote %u items\n", iniGetSectionCount(outlist,NULL)); ! 773: ! 774: strListFree(&outlist); ! 775: ! 776: return(success); ! 777: } ! 778: ! 779: BOOL upgrade_filters() ! 780: { ! 781: char inpath[MAX_PATH+1]; ! 782: char outpath[MAX_PATH+1]; ! 783: char msgpath[MAX_PATH+1]; ! 784: ! 785: if(!upgrade_ip_filters()) ! 786: return(FALSE); ! 787: ! 788: sprintf(inpath,"%shost.can",scfg.text_dir); ! 789: sprintf(msgpath,"%sbadhost.msg",scfg.text_dir); ! 790: sprintf(outpath,"%shost-filter.ini",scfg.ctrl_dir); ! 791: if(!upgrade_filter("Hostname",inpath,msgpath,outpath)) ! 792: return(FALSE); ! 793: ! 794: sprintf(inpath,"%semail.can",scfg.text_dir); ! 795: sprintf(msgpath,"%sbademail.msg",scfg.text_dir); ! 796: sprintf(outpath,"%semail-filter.ini",scfg.ctrl_dir); ! 797: if(!upgrade_filter("E-mail Address",inpath,msgpath,outpath)) ! 798: return(FALSE); ! 799: ! 800: sprintf(inpath,"%sname.can",scfg.text_dir); ! 801: sprintf(msgpath,"%sbadname.msg",scfg.text_dir); ! 802: sprintf(outpath,"%sname-filter.ini",scfg.ctrl_dir); ! 803: if(!upgrade_filter("User Name",inpath,msgpath,outpath)) ! 804: return(FALSE); ! 805: ! 806: sprintf(inpath,"%sphone.can",scfg.text_dir); ! 807: sprintf(msgpath,"%sbadphone.msg",scfg.text_dir); ! 808: sprintf(outpath,"%sphone-filter.ini",scfg.ctrl_dir); ! 809: if(!upgrade_filter("Phone Number",inpath,msgpath,outpath)) ! 810: return(FALSE); ! 811: ! 812: sprintf(inpath,"%ssubject.can",scfg.text_dir); ! 813: sprintf(msgpath,"%sbadsubject.msg",scfg.text_dir); ! 814: sprintf(outpath,"%ssubject-filter.ini",scfg.ctrl_dir); ! 815: if(!upgrade_filter("Message Subject",inpath,msgpath,outpath)) ! 816: return(FALSE); ! 817: ! 818: return(TRUE); ! 819: } ! 820: ! 821: #define BBS_VIRTUAL_PATH "bbs:/""/" /* this is actually bbs:<slash><slash> */ ! 822: ! 823: BOOL upgrade_ftp_aliases(void) ! 824: { ! 825: char* p; ! 826: char* path; ! 827: char* desc; ! 828: char* section; ! 829: char inpath[MAX_PATH+1]; ! 830: char outpath[MAX_PATH+1]; ! 831: FILE* in; ! 832: FILE* out; ! 833: BOOL success; ! 834: size_t i; ! 835: size_t total; ! 836: str_list_t inlist; ! 837: str_list_t outlist; ! 838: ! 839: style.section_separator = ""; ! 840: iniSetDefaultStyle(style); ! 841: ! 842: SAFEPRINTF(inpath,"%sftpalias.cfg",scfg.ctrl_dir); ! 843: SAFEPRINTF(outpath,"%sftpalias.ini",scfg.ctrl_dir); ! 844: ! 845: if(!fexistcase(inpath)) ! 846: return(TRUE); ! 847: ! 848: printf("Upgrading FTP Aliases...\n"); ! 849: ! 850: if(!overwrite(outpath)) ! 851: return(TRUE); ! 852: if((out=fopen(outpath,"w"))==NULL) { ! 853: perror(outpath); ! 854: return(FALSE); ! 855: } ! 856: ! 857: if((outlist = strListInit())==NULL) { ! 858: printf("!malloc failure\n"); ! 859: return(FALSE); ! 860: } ! 861: printf("\t%s ",inpath); ! 862: if((in=fopen(inpath,"r"))==NULL) { ! 863: perror("open failure"); ! 864: return(FALSE); ! 865: } ! 866: ! 867: if((inlist = strListReadFile(in,NULL,4096))==NULL) { ! 868: printf("!failure reading %s\n",inpath); ! 869: return(FALSE); ! 870: } ! 871: ! 872: total=0; ! 873: for(i=0;inlist[i]!=NULL;i++) { ! 874: p=truncsp(inlist[i]); ! 875: SKIP_WHITESPACE(p); ! 876: if(*p==';') { ! 877: strListPush(&outlist,p); ! 878: continue; ! 879: } else if(*p==0) ! 880: continue; ! 881: path=p; ! 882: FIND_WHITESPACE(path); ! 883: if(*path==0) ! 884: continue; ! 885: *(path++)=0; ! 886: SKIP_WHITESPACE(path); ! 887: desc=path; ! 888: FIND_WHITESPACE(desc); ! 889: if(*desc==0) ! 890: continue; ! 891: *(desc++)=0; ! 892: SKIP_WHITESPACE(desc); ! 893: iniAppendSection(&outlist,p,NULL); ! 894: if(!strnicmp(path,BBS_VIRTUAL_PATH,strlen(BBS_VIRTUAL_PATH))) ! 895: path+=strlen(BBS_VIRTUAL_PATH)-1; ! 896: else ! 897: iniSetBool(&outlist,p,"Local",TRUE,NULL); ! 898: iniSetString(&outlist,p,"Path",path,NULL); ! 899: if(!stricmp(desc,"hidden")) ! 900: iniSetBool(&outlist,p,"Hidden",TRUE,NULL); ! 901: else ! 902: iniSetString(&outlist,p,"Description",desc,NULL); ! 903: total++; ! 904: } ! 905: ! 906: section="local"; ! 907: iniAppendSection(&outlist,section,NULL); ! 908: iniSetString(&outlist,section,"Description","Local file system",NULL); ! 909: iniSetString(&outlist,section,"Path","/",NULL); ! 910: iniSetBool(&outlist,section,"Local",TRUE,NULL); ! 911: iniSetString(&outlist,section,"AccessRequirements","SYSOP",NULL); ! 912: ! 913: printf("-> %s (%u FTP aliases)\n", outpath, total); ! 914: fclose(in); ! 915: strListFree(&inlist); ! 916: ! 917: success=iniWriteFile(out, outlist); ! 918: ! 919: fclose(out); ! 920: ! 921: if(!success) { ! 922: printf("!iniWriteFile failure\n"); ! 923: return(FALSE); ! 924: } ! 925: ! 926: printf("\tWrote %u total FTP aliases\n", iniGetSectionCount(outlist,NULL)); ! 927: ! 928: strListFree(&outlist); ! 929: ! 930: return(success); ! 931: } ! 932: ! 933: BOOL upgrade_socket_options(void) ! 934: { ! 935: char* p; ! 936: char* key; ! 937: char* val; ! 938: char* section; ! 939: char inpath[MAX_PATH+1]; ! 940: char outpath[MAX_PATH+1]; ! 941: FILE* in; ! 942: FILE* out; ! 943: BOOL success; ! 944: size_t i; ! 945: size_t total; ! 946: str_list_t inlist; ! 947: str_list_t outlist; ! 948: ! 949: style.section_separator = ""; ! 950: iniSetDefaultStyle(style); ! 951: ! 952: SAFEPRINTF(inpath,"%ssockopts.cfg",scfg.ctrl_dir); ! 953: SAFEPRINTF(outpath,"%ssockopts.ini",scfg.ctrl_dir); ! 954: ! 955: if(!fexistcase(inpath)) ! 956: return(TRUE); ! 957: ! 958: printf("Upgrading Socket Options...\n"); ! 959: ! 960: if(!overwrite(outpath)) ! 961: return(TRUE); ! 962: if((out=fopen(outpath,"w"))==NULL) { ! 963: perror(outpath); ! 964: return(FALSE); ! 965: } ! 966: ! 967: if((outlist = strListInit())==NULL) { ! 968: printf("!malloc failure\n"); ! 969: return(FALSE); ! 970: } ! 971: printf("\t%s ",inpath); ! 972: if((in=fopen(inpath,"r"))==NULL) { ! 973: perror("open failure"); ! 974: return(FALSE); ! 975: } ! 976: ! 977: if((inlist = strListReadFile(in,NULL,4096))==NULL) { ! 978: printf("!failure reading %s\n",inpath); ! 979: return(FALSE); ! 980: } ! 981: ! 982: total=0; ! 983: for(i=0;inlist[i]!=NULL;i++) { ! 984: p=truncsp(inlist[i]); ! 985: SKIP_WHITESPACE(p); ! 986: if(*p==';') { ! 987: strListPush(&outlist,p); ! 988: continue; ! 989: } else if(*p==0) ! 990: continue; ! 991: key=p; ! 992: FIND_WHITESPACE(p); ! 993: if(*p==0) ! 994: continue; ! 995: *(p++)=0; ! 996: SKIP_WHITESPACE(p); ! 997: val=p; ! 998: section=ROOT_SECTION; ! 999: if(!stricmp(key,"tcp_nodelay")) ! 1000: section="telnet|rlogin"; ! 1001: else if(!stricmp(key,"keepalive")) ! 1002: section="tcp"; ! 1003: iniSetString(&outlist,section,key,val,NULL); ! 1004: total++; ! 1005: } ! 1006: ! 1007: printf("-> %s (%u Socket Options)\n", outpath, total); ! 1008: fclose(in); ! 1009: strListFree(&inlist); ! 1010: ! 1011: success=iniWriteFile(out, outlist); ! 1012: ! 1013: fclose(out); ! 1014: ! 1015: if(!success) { ! 1016: printf("!iniWriteFile failure\n"); ! 1017: return(FALSE); ! 1018: } ! 1019: ! 1020: strListFree(&outlist); ! 1021: ! 1022: return(success); ! 1023: } ! 1024: ! 1025: ! 1026: ! 1027: #define upg_iniSetString(list,section,key,val) \ ! 1028: if(*val) iniSetString(list,section,key,val,NULL) ! 1029: ! 1030: #define upg_iniSetInteger(list,section,key,val) \ ! 1031: if(val) iniSetInteger(list,section,key,val,NULL) ! 1032: ! 1033: BOOL upgrade_msg_areas(void) ! 1034: { ! 1035: char str[128]; ! 1036: char outpath[MAX_PATH+1]; ! 1037: char data_subs[MAX_PATH+1]; ! 1038: FILE* out; ! 1039: BOOL success; ! 1040: size_t i; ! 1041: str_list_t outlist; ! 1042: ! 1043: style.section_separator = ""; ! 1044: iniSetDefaultStyle(style); ! 1045: ! 1046: SAFEPRINTF(outpath,"%smsg_areas.ini",scfg.ctrl_dir); ! 1047: ! 1048: SAFEPRINTF(data_subs,"%ssubs",scfg.data_dir); ! 1049: backslash(data_subs); ! 1050: ! 1051: printf("Upgrading Message Area configuration...\n"); ! 1052: ! 1053: if(!overwrite(outpath)) ! 1054: return(TRUE); ! 1055: if((out=fopen(outpath,"w"))==NULL) { ! 1056: perror(outpath); ! 1057: return(FALSE); ! 1058: } ! 1059: ! 1060: if((outlist = strListInit())==NULL) { ! 1061: printf("!malloc failure\n"); ! 1062: return(FALSE); ! 1063: } ! 1064: ! 1065: for(i=0; i<scfg.total_grps; i++) { ! 1066: SAFEPRINTF(str,"Group:%s",scfg.grp[i]->sname); ! 1067: iniAppendSection(&outlist,str,NULL); ! 1068: upg_iniSetString(&outlist,str,"Description",scfg.grp[i]->lname); ! 1069: upg_iniSetString(&outlist,str,"AccessRequirements",scfg.grp[i]->arstr); ! 1070: upg_iniSetString(&outlist,str,"CodePrefix",scfg.grp[i]->code_prefix); ! 1071: } ! 1072: for(i=0; i<scfg.total_subs; i++) { ! 1073: sprintf(str,"%s",scfg.sub[i]->code_suffix); ! 1074: iniAppendSection(&outlist,str,NULL); ! 1075: upg_iniSetString(&outlist,str,"Group",scfg.grp[scfg.sub[i]->grp]->sname); ! 1076: upg_iniSetString(&outlist,str,"Name",scfg.sub[i]->sname); ! 1077: upg_iniSetString(&outlist,str,"Newsgroup",scfg.sub[i]->newsgroup); ! 1078: upg_iniSetString(&outlist,str,"QwkName",scfg.sub[i]->qwkname); ! 1079: upg_iniSetInteger(&outlist,str,"QwkConference",scfg.sub[i]->qwkconf); ! 1080: upg_iniSetString(&outlist,str,"Description",scfg.sub[i]->lname); ! 1081: if(stricmp(scfg.sub[i]->data_dir, data_subs)) ! 1082: iniSetString(&outlist,str,"DataDir",scfg.sub[i]->data_dir,NULL); ! 1083: if(strcmp(scfg.sub[i]->tagline, scfg.qnet_tagline)) ! 1084: upg_iniSetString(&outlist,str,"TagLine",scfg.sub[i]->tagline); ! 1085: if(strcmp(scfg.origline, scfg.sub[i]->origline)) ! 1086: upg_iniSetString(&outlist,str,"OriginLine",scfg.sub[i]->origline); ! 1087: upg_iniSetString(&outlist,str,"AccessRequirements",scfg.sub[i]->arstr); ! 1088: upg_iniSetString(&outlist,str,"ReadRequirements",scfg.sub[i]->read_arstr); ! 1089: upg_iniSetString(&outlist,str,"PostRequirements",scfg.sub[i]->post_arstr); ! 1090: upg_iniSetString(&outlist,str,"OperatorRequirements",scfg.sub[i]->op_arstr); ! 1091: upg_iniSetString(&outlist,str,"ModeratorRequirements",scfg.sub[i]->mod_arstr); ! 1092: upg_iniSetString(&outlist,str,"PostSemFile",scfg.sub[i]->post_sem); ! 1093: upg_iniSetInteger(&outlist,str,"MaxMessages",scfg.sub[i]->maxmsgs); ! 1094: upg_iniSetInteger(&outlist,str,"MaxMessageAge",scfg.sub[i]->maxage); ! 1095: upg_iniSetInteger(&outlist,str,"CrcHistory",scfg.sub[i]->maxcrcs); ! 1096: if(scfg.sub[i]->faddr.zone) ! 1097: iniSetString(&outlist,str,"FidoNetAddress",smb_faddrtoa(&scfg.sub[i]->faddr,NULL),NULL); ! 1098: } ! 1099: printf("-> %s (%u groups and %u sub-boards)\n", outpath, scfg.total_grps, scfg.total_subs); ! 1100: ! 1101: success=iniWriteFile(out, outlist); ! 1102: ! 1103: fclose(out); ! 1104: ! 1105: if(!success) { ! 1106: printf("!iniWriteFile failure\n"); ! 1107: return(FALSE); ! 1108: } ! 1109: ! 1110: printf("\tWrote %u items\n", iniGetSectionCount(outlist,NULL)); ! 1111: ! 1112: strListFree(&outlist); ! 1113: ! 1114: return(success); ! 1115: } ! 1116: ! 1117: ! 1118: char *usage="\nusage: v4upgrade [ctrl_dir]\n"; ! 1119: ! 1120: int main(int argc, char** argv) ! 1121: { ! 1122: char error[512]; ! 1123: char revision[16]; ! 1124: char* p; ! 1125: int first_arg=1; ! 1126: ! 1127: sscanf("$Revision: 1.13 $", "%*s %s", revision); ! 1128: ! 1129: fprintf(stderr,"\nV4upgrade v%s-%s - Upgrade Synchronet files from v3 to v4\n" ! 1130: ,revision ! 1131: ,PLATFORM_DESC ! 1132: ); ! 1133: ! 1134: if(argc>1 && strcspn(argv[first_arg],"/\\")!=strlen(argv[first_arg])) ! 1135: p=argv[first_arg++]; ! 1136: else ! 1137: p=getenv("SBBSCTRL"); ! 1138: if(p==NULL) { ! 1139: printf("\nSBBSCTRL environment variable not set.\n"); ! 1140: printf("\nExample: SET SBBSCTRL=/sbbs/ctrl\n"); ! 1141: exit(1); ! 1142: } ! 1143: ! 1144: memset(&scfg,0,sizeof(scfg)); ! 1145: scfg.size=sizeof(scfg); ! 1146: SAFECOPY(scfg.ctrl_dir,p); ! 1147: ! 1148: if(chdir(scfg.ctrl_dir)!=0) ! 1149: fprintf(stderr,"!ERROR changing directory to: %s", scfg.ctrl_dir); ! 1150: ! 1151: printf("\nLoading configuration files from %s\n",scfg.ctrl_dir); ! 1152: if(!load_cfg(&scfg,NULL,TRUE,error)) { ! 1153: fprintf(stderr,"!ERROR loading configuration files: %s\n",error); ! 1154: exit(1); ! 1155: } ! 1156: ! 1157: iniSetDefaultStyle(style); ! 1158: ! 1159: if(!upgrade_users()) ! 1160: return(1); ! 1161: ! 1162: if(!upgrade_stats()) ! 1163: return(2); ! 1164: ! 1165: if(!upgrade_event_data()) ! 1166: return(3); ! 1167: ! 1168: if(!upgrade_filters()) ! 1169: return(4); ! 1170: ! 1171: if(!upgrade_list("Twits", "twitlist.cfg", "twitlist.ini", TRUE, NULL)) ! 1172: return(5); ! 1173: ! 1174: if(!upgrade_list("RLogin allow", "rlogin.cfg", "rlogin.ini", TRUE, NULL)) ! 1175: return(5); ! 1176: ! 1177: if(!upgrade_list("E-Mail aliases", "alias.cfg", "alias.ini", FALSE, NULL)) ! 1178: return(5); ! 1179: ! 1180: if(!upgrade_list("E-Mail domains", "domains.cfg", "domains.ini", TRUE, NULL)) ! 1181: return(5); ! 1182: ! 1183: if(!upgrade_list("Allowed mail relayers", "relay.cfg", "relay.ini", TRUE, NULL)) ! 1184: return(5); ! 1185: ! 1186: if(!upgrade_list("SPAM bait addresses", "spambait.cfg", "spambait.ini", TRUE, NULL)) ! 1187: return(5); ! 1188: ! 1189: if(!upgrade_list("Blocked spammers", "spamblock.cfg", "spamblock.ini", TRUE, NULL)) ! 1190: return(5); ! 1191: ! 1192: if(!upgrade_list("DNS black-lists", "dns_blacklist.cfg", "dns_blacklist.ini", TRUE, "notice")) ! 1193: return(5); ! 1194: ! 1195: if(!upgrade_list("DNS black-list exemptions", "dnsbl_exempt.cfg", "dnsbl_exempt.ini", TRUE, NULL)) ! 1196: return(5); ! 1197: ! 1198: if(!upgrade_ftp_aliases()) ! 1199: return(-1); ! 1200: ! 1201: if(!upgrade_socket_options()) ! 1202: return(-1); ! 1203: ! 1204: /* attr.cfg */ ! 1205: ! 1206: if(!upgrade_msg_areas()) ! 1207: return(-1); ! 1208: ! 1209: printf("Upgrade successful.\n"); ! 1210: return(0); ! 1211: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.