home *** CD-ROM | disk | FTP | other *** search
/ PC Online 1998 September / PCO_0998.ISO / filesbbs / dos / sbbs_src.exe / SBBS / SMM / SMMUTIL.C < prev    next >
Encoding:
C/C++ Source or Header  |  1997-04-13  |  20.3 KB  |  712 lines

  1. /* SMMUTIL.C */
  2.  
  3. /* Developed 1990-1997 by Rob Swindell; PO Box 501, Yorba Linda, CA 92885 */
  4.  
  5. #include <stdio.h>
  6. #include <time.h>
  7. #include <stdlib.h>
  8. #include <io.h>
  9. #include <dos.h>
  10. #include <fcntl.h>
  11. #include <sys\stat.h>
  12. #include <malloc.h>
  13. #include <stdarg.h>
  14. #include "gen_defs.h"
  15. #include "smmdefs.h"
  16. #include "crc32.h"
  17.  
  18. struct date date;
  19. struct time curtime;
  20.  
  21. FILE *log=NULL;
  22.  
  23. /****************************************************************************/
  24. /* Returns 32-crc of string (not counting terminating NULL)                 */
  25. /****************************************************************************/
  26. ulong crc32(char *str)
  27. {
  28.     int i=0;
  29.     ulong crc=0xffffffffUL;
  30.  
  31.     while(str[i])
  32.         crc=ucrc32(str[i++],crc);
  33.     crc=~crc;
  34.     return(crc);
  35. }
  36.  
  37. /****************************************************************************/
  38. /* Returns the age derived from the string 'birth' in the format MM/DD/YY    */
  39. /****************************************************************************/
  40. char getage(char *birth)
  41. {
  42.     char age;
  43.  
  44. if(birth[0]<=SP)
  45.     return(0);
  46. getdate(&date);
  47. age=(date.da_year-1900)-(((birth[6]&0xf)*10)+(birth[7]&0xf));
  48. if(atoi(birth)>12 || atoi(birth+3)>31)
  49.     return(0);
  50. if(((birth[0]&0xf)*10)+(birth[1]&0xf)>date.da_mon ||
  51.     (((birth[0]&0xf)*10)+(birth[1]&0xf)==date.da_mon &&
  52.     ((birth[3]&0xf)*10)+(birth[4]&0xf)>date.da_day))
  53.     age--;
  54. if(age<0)
  55.     return(0);
  56. return(age);
  57. }
  58.  
  59. /**********************/
  60. /* Log print function */
  61. /**********************/
  62. void logprintf(char *str, ...)
  63. {
  64.     va_list argptr;
  65.     char buf[256];
  66.     time_t now;
  67.     struct tm *gm;
  68.  
  69. va_start(argptr,str);
  70. vsprintf(buf,str,argptr);
  71. va_end(argptr);
  72. fprintf(stderr,"\n%s",buf);
  73. if(!log) return;
  74. now=time(NULL);
  75. gm=localtime(&now);
  76. fseek(log,0L,SEEK_END);
  77. fprintf(log,"%02u/%02u/%02u %02u:%02u:%02u %s\r\n"
  78.     ,gm->tm_mon+1,gm->tm_mday,gm->tm_year,gm->tm_hour,gm->tm_min,gm->tm_sec
  79.     ,buf);
  80. fflush(log);
  81. }
  82.  
  83.  
  84. char *base41(unsigned int i, char *str)
  85. {
  86.     char c;
  87.     unsigned int j=41*41,k;
  88.  
  89. for(c=0;c<3;c++) {
  90.     k=i/j;
  91.     str[c]='0'+k;
  92.     i-=(k*j);
  93.     j/=41;
  94.     if(str[c]>=':')
  95.         str[c]='A'+(str[c]-':');
  96.     if(str[c]>='[')
  97.         str[c]='#'+(str[c]-'['); }
  98. str[c]=0;
  99. return(str);
  100. }
  101.  
  102. /****************************************************************************/
  103. /* Updates 16-bit "rcrc" with character 'ch'                                */
  104. /****************************************************************************/
  105. void ucrc16(uchar ch, ushort *rcrc) {
  106.     ushort i, cy;
  107.     uchar nch=ch;
  108.  
  109. for (i=0; i<8; i++) {
  110.     cy=*rcrc & 0x8000;
  111.     *rcrc<<=1;
  112.     if (nch & 0x80) *rcrc |= 1;
  113.     nch<<=1;
  114.     if (cy) *rcrc ^= 0x1021; }
  115. }
  116.  
  117. /****************************************************************************/
  118. /* Returns 16-crc of string (not counting terminating NULL)                 */
  119. /****************************************************************************/
  120. ushort crc16(char *str)
  121. {
  122.     int     i=0;
  123.     ushort  crc=0;
  124.  
  125. ucrc16(0,&crc);
  126. while(str[i])
  127.     ucrc16(str[i++],&crc);
  128. ucrc16(0,&crc);
  129. ucrc16(0,&crc);
  130. return(crc);
  131. }
  132.  
  133.  
  134. void delphoto(user_t user)
  135. {
  136.     char fname[64],path[128],tmp[128];
  137.     int i;
  138.     struct ffblk ff;
  139.  
  140. if(!(user.misc&USER_PHOTO))
  141.     return;
  142. for(i=0;user.system[i];i++)
  143.     if(isalnum(user.system[i]))
  144.         break;
  145. if(!user.system[i])
  146.     fname[0]='~';
  147. else
  148.     fname[0]=user.system[i];
  149. for(i=strlen(user.system)-1;i>0;i--)
  150.     if(isalnum(user.system[i]))
  151.         break;
  152. if(i<=0)
  153.     fname[1]='~';
  154. else
  155.     fname[1]=user.system[i];
  156. fname[2]=0;
  157. strupr(user.system);
  158. strcat(fname,base41(crc16(user.system),tmp));
  159. strcat(fname,base41(user.number,tmp));
  160. strcat(fname,".*");
  161. strupr(fname);
  162. sprintf(path,"PHOTO\\%s",fname);
  163. i=findfirst(path,&ff,0);
  164. if(i)
  165.     return;
  166. sprintf(path,"PHOTO\\%s",ff.ff_name);
  167. if(remove(path))
  168.     logprintf("Photo (%s) couldn't be removed!",path);
  169. else
  170.     logprintf("Photo (%s) removed",path);
  171. }
  172.  
  173.  
  174. int main(int argc, char **argv)
  175. {
  176.     int  i,file,max_age=0,max_wall=0,age;
  177.     long l,m,total_ixbs=0
  178.         ,users=0,photos=0,networked=0
  179.         ,male_straight=0
  180.         ,male_gay=0
  181.         ,male_bi=0
  182.         ,female_straight=0
  183.         ,female_gay=0
  184.         ,female_bi=0
  185.         ,age12=0
  186.         ,age15=0
  187.         ,age20=0,age25=0
  188.         ,age30=0,age35=0
  189.         ,age40=0,age45=0
  190.         ,age50=0,age55=0
  191.         ,age60=0,age65=0
  192.         ,age70=0,age71=0
  193.         ,zodiac_aries=0
  194.         ,zodiac_taurus=0
  195.         ,zodiac_gemini=0
  196.         ,zodiac_cancer=0
  197.         ,zodiac_leo=0
  198.         ,zodiac_virgo=0
  199.         ,zodiac_libra=0
  200.         ,zodiac_scorpio=0
  201.         ,zodiac_sagittarius=0
  202.         ,zodiac_capricorn=0
  203.         ,zodiac_aquarius=0
  204.         ,zodiac_pisces=0
  205.         ,hair_blonde=0
  206.         ,hair_brown=0
  207.         ,hair_red=0
  208.         ,hair_black=0
  209.         ,hair_grey=0
  210.         ,hair_other=0
  211.         ,eyes_blue=0
  212.         ,eyes_green=0
  213.         ,eyes_hazel=0
  214.         ,eyes_brown=0
  215.         ,eyes_other=0
  216.         ,race_white=0
  217.         ,race_black=0
  218.         ,race_hispanic=0
  219.         ,race_asian=0
  220.         ,race_amerindian=0
  221.         ,race_mideastern=0
  222.         ,race_other=0
  223.         ,marital_single=0
  224.         ,marital_married=0
  225.         ,marital_divorced=0
  226.         ,marital_widowed=0
  227.         ,marital_other=0
  228.         ;
  229.     FILE *ixb_fp,*dab_fp,*tmp_fp;
  230.     ixb_t huge *ixb=NULL,ixbrec;
  231.     user_t user;
  232.     wall_t wall;
  233.     time_t now;
  234.  
  235. fprintf(stderr,"\nSMMUTIL · Synchronet Match Maker Utility · v2.01ß\n\n");
  236.  
  237. for(i=1;i<argc;i++)
  238.     if(isdigit(argv[i][0])) {
  239.         if(max_age)
  240.             max_wall=atoi(argv[i]);
  241.         else
  242.             max_age=atoi(argv[i]); }
  243.     else {
  244.         printf("usage: SMMUTIL max_profile_age_in_days "
  245.             "max_wall_writing_age_in_days\n");
  246.         printf("\n");
  247.         printf("example: SMMUTIL 90 7\n");
  248.         exit(1); }
  249.  
  250. if((file=open("SMM.IXB",O_RDWR|O_BINARY|O_CREAT|O_DENYNONE
  251.     ,S_IWRITE|S_IREAD))==-1
  252.     || (ixb_fp=fdopen(file,"r+b"))==NULL) {
  253.     printf("Error opening SMM.IXB\n");
  254.     exit(1); }
  255.  
  256. if((file=open("SMM.DAB",O_RDWR|O_BINARY|O_DENYNONE))==-1
  257.     || (dab_fp=fdopen(file,"r+b"))==NULL) {
  258.     printf("Error opening SMM.DAB\n");
  259.     exit(1); }
  260.  
  261. if((file=open("SMM.TMP",O_WRONLY|O_CREAT|O_TRUNC|O_BINARY|O_DENYALL
  262.     ,S_IWRITE|S_IREAD))==-1
  263.     || (tmp_fp=fdopen(file,"r+b"))==NULL) {
  264.     printf("Error opening SMM.TMP\n");
  265.     exit(1); }
  266.  
  267. if((file=open("SMMUTIL.LOG",O_WRONLY|O_CREAT|O_APPEND|O_BINARY|O_DENYALL
  268.     ,S_IWRITE|S_IREAD))==-1
  269.     || (log=fdopen(file,"w+b"))==NULL) {
  270.     printf("Error opening SMMUTIL.LOG\n");
  271.     exit(1); }
  272.  
  273. fprintf(stderr,"Reading profile data...");
  274. rewind(dab_fp);
  275. while(!feof(dab_fp)) {
  276.     if(!fread(&user,sizeof(user_t),1,dab_fp))
  277.         break;
  278.     if((ixb=REALLOC(ixb,sizeof(ixb_t)*(total_ixbs+1)))==NULL) {
  279.         printf("Malloc error\n");
  280.         exit(1); }
  281.     user.name[25]=0;
  282.     strupr(user.name);
  283.     ixb[total_ixbs].name=crc32(user.name);
  284.     user.system[25]=0;
  285.     strupr(user.system);
  286.     ixb[total_ixbs].system=crc32(user.system);
  287.     ixb[total_ixbs].updated=user.updated;
  288.     if(user.misc&USER_DELETED)
  289.         ixb[total_ixbs].number=0;
  290.     else
  291.         ixb[total_ixbs].number=user.number;
  292.     total_ixbs++; }
  293. fprintf(stderr,"\n");
  294.  
  295. now=time(NULL);
  296. fprintf(stderr,"Creating new profile index and data files...");
  297. chsize(fileno(ixb_fp),0);
  298. rewind(ixb_fp);
  299. rewind(tmp_fp);
  300. for(l=0;l<total_ixbs;l++) {
  301.     fseek(dab_fp,l*sizeof(user_t),SEEK_SET);
  302.     if(!fread(&user,sizeof(user_t),1,dab_fp)) {
  303.         logprintf("%04lX Couldn't read user record",l);
  304.         continue; }
  305.  
  306.     /* Make sure all strings are NULL terminated */
  307.     user.name[25]=user.realname[25]=user.system[40]=user.birth[8]=0;
  308.     user.zipcode[10]=user.location[30]=0;
  309.     user.min_zipcode[10]=user.max_zipcode[10]=0;
  310.     for(i=0;i<5;i++)
  311.         user.note[i][50]=0;
  312.  
  313.     if(!ixb[l].number) {
  314.         logprintf("%04lX %5lu %-25s Deleted user"
  315.             ,l,user.number,user.system);
  316.         delphoto(user);
  317.         continue; }
  318.     if(ixb[l].number&0xffff0000UL) {
  319.         logprintf("%04lX %5lu %-25s Invalid user number"
  320.             ,l,ixb[l].number,user.system);
  321.         delphoto(user);
  322.         continue; }
  323.     if(max_age
  324.         && now>ixb[l].updated    // Not in the future
  325.         && (now-ixb[l].updated)/(24UL*60UL*60UL)>max_age) {
  326.         logprintf("%04lX %5lu %-25s Not updated in %lu days"
  327.             ,l,user.number,user.system,(now-ixb[l].updated)/(24UL*60UL*60UL));
  328.         delphoto(user);
  329.         continue; }
  330.     for(m=l+1;m<total_ixbs;m++)
  331.         if(ixb[l].number
  332.             && ixb[l].number==ixb[m].number && ixb[l].system==ixb[m].system)
  333.             break;
  334.     if(m<total_ixbs) {        /* Duplicate found! */
  335.         logprintf("%04lX %5lu %-25s Duplicate user"
  336.             ,l,user.number,user.system);
  337.         delphoto(user);
  338.         continue; }
  339.  
  340.     if(user.name[0]<SP || user.realname[0]<SP || user.system[0]<SP
  341.         || user.location[0]<SP || user.zipcode[0]<SP || user.birth[0]<SP) {
  342.         logprintf("%04lX %5lu %-25s Invalid user string"
  343.             ,l,user.number,user.system);
  344.         delphoto(user);
  345.         continue; }
  346.     if(!user.sex || !user.marital || !user.race || !user.hair || !user.eyes) {
  347.         logprintf("%04lX %5lu %-25s Null field"
  348.             ,l,user.number,user.system);
  349.         delphoto(user);
  350.         continue; }
  351.     if(user.sex=='M') {
  352.         if(user.pref_sex=='F')
  353.             male_straight++;
  354.         else if(user.pref_sex=='M')
  355.             male_gay++;
  356.         else
  357.             male_bi++; }
  358.     else if(user.sex=='F') {
  359.         if(user.pref_sex=='M')
  360.             female_straight++;
  361.         else if(user.pref_sex=='F')
  362.             female_gay++;
  363.         else
  364.             female_bi++; }
  365.     else {
  366.         logprintf("%04lX %5lu %-25s Invalid sex (%02X)"
  367.             ,l,user.number,user.system,user.sex);
  368.         delphoto(user);
  369.         continue; }
  370.     users++;
  371.     if(user.misc&USER_PHOTO)
  372.         photos++;
  373.     if(user.misc&USER_FROMSMB)
  374.         networked++;
  375.     age=getage(user.birth);
  376.     if(age<13) age12++;
  377.     else if(age<16) age15++;
  378.     else if(age<21) age20++;
  379.     else if(age<26) age25++;
  380.     else if(age<31) age30++;
  381.     else if(age<36) age35++;
  382.     else if(age<41) age40++;
  383.     else if(age<46) age45++;
  384.     else if(age<51) age50++;
  385.     else if(age<56) age55++;
  386.     else if(age<61) age60++;
  387.     else if(age<66) age65++;
  388.     else if(age<71) age70++;
  389.     else age71++;
  390.     switch(user.hair) {
  391.         case HAIR_BLONDE:
  392.             hair_blonde++;
  393.             break;
  394.         case HAIR_BROWN:
  395.             hair_brown++;
  396.             break;
  397.         case HAIR_RED:
  398.             hair_red++;
  399.             break;
  400.         case HAIR_BLACK:
  401.             hair_black++;
  402.             break;
  403.         case HAIR_GREY:
  404.             hair_grey++;
  405.             break;
  406.         default:
  407.             hair_other++;
  408.             break; }
  409.  
  410.     switch(user.eyes) {
  411.         case EYES_BLUE:
  412.             eyes_blue++;
  413.             break;
  414.         case EYES_BROWN:
  415.             eyes_brown++;
  416.             break;
  417.         case EYES_GREEN:
  418.             eyes_green++;
  419.             break;
  420.         case EYES_HAZEL:
  421.             eyes_hazel++;
  422.             break;
  423.         default:
  424.             eyes_other++;
  425.             break; }
  426.     switch(user.marital) {
  427.         case MARITAL_SINGLE:
  428.             marital_single++;
  429.             break;
  430.         case MARITAL_MARRIED:
  431.             marital_married++;
  432.             break;
  433.         case MARITAL_DIVORCED:
  434.             marital_divorced++;
  435.             break;
  436.         case MARITAL_WIDOWED:
  437.             marital_widowed++;
  438.             break;
  439.         default:
  440.             marital_other++;
  441.             break; }
  442.  
  443.     switch(user.race) {
  444.         case RACE_WHITE:
  445.             race_white++;
  446.             break;
  447.         case RACE_BLACK:
  448.             race_black++;
  449.             break;
  450.         case RACE_HISPANIC:
  451.             race_hispanic++;
  452.             break;
  453.         case RACE_ASIAN:
  454.             race_asian++;
  455.             break;
  456.         case RACE_AMERINDIAN:
  457.             race_amerindian++;
  458.             break;
  459.         case RACE_MIDEASTERN:
  460.             race_mideastern++;
  461.             break;
  462.         default:
  463.             race_other++;
  464.             break; }
  465.  
  466.     if((!strncmp(user.birth,"03",2) && atoi(user.birth+3)>=21)
  467.         || (!strncmp(user.birth,"04",2) && atoi(user.birth+3)<=19))
  468.         zodiac_aries++;
  469.     else if((!strncmp(user.birth,"04",2) && atoi(user.birth+3)>=20)
  470.         || (!strncmp(user.birth,"05",2) && atoi(user.birth+3)<=20))
  471.         zodiac_taurus++;
  472.     else if((!strncmp(user.birth,"05",2) && atoi(user.birth+3)>=21)
  473.         || (!strncmp(user.birth,"06",2) && atoi(user.birth+3)<=20))
  474.         zodiac_gemini++;
  475.     else if((!strncmp(user.birth,"06",2) && atoi(user.birth+3)>=21)
  476.         || (!strncmp(user.birth,"07",2) && atoi(user.birth+3)<=22))
  477.         zodiac_cancer++;
  478.     else if((!strncmp(user.birth,"07",2) && atoi(user.birth+3)>=23)
  479.         || (!strncmp(user.birth,"08",2) && atoi(user.birth+3)<=22))
  480.         zodiac_leo++;
  481.     else if((!strncmp(user.birth,"08",2) && atoi(user.birth+3)>=23)
  482.         || (!strncmp(user.birth,"09",2) && atoi(user.birth+3)<=22))
  483.         zodiac_virgo++;
  484.     else if((!strncmp(user.birth,"09",2) && atoi(user.birth+3)>=23)
  485.         || (!strncmp(user.birth,"10",2) && atoi(user.birth+3)<=22))
  486.         zodiac_libra++;
  487.     else if((!strncmp(user.birth,"10",2) && atoi(user.birth+3)>=23)
  488.         || (!strncmp(user.birth,"11",2) && atoi(user.birth+3)<=21))
  489.         zodiac_scorpio++;
  490.     else if((!strncmp(user.birth,"11",2) && atoi(user.birth+3)>=22)
  491.         || (!strncmp(user.birth,"12",2) && atoi(user.birth+3)<=21))
  492.         zodiac_sagittarius++;
  493.     else if((!strncmp(user.birth,"12",2) && atoi(user.birth+3)>=22)
  494.         || (!strncmp(user.birth,"01",2) && atoi(user.birth+3)<=19))
  495.         zodiac_capricorn++;
  496.     else if((!strncmp(user.birth,"01",2) && atoi(user.birth+3)>=20)
  497.         || (!strncmp(user.birth,"02",2) && atoi(user.birth+3)<=18))
  498.         zodiac_aquarius++;
  499.     else if((!strncmp(user.birth,"02",2) && atoi(user.birth+3)>=19)
  500.         || (!strncmp(user.birth,"03",2) && atoi(user.birth+3)<=20))
  501.         zodiac_pisces++;
  502.  
  503.     fwrite(&ixb[l],sizeof(ixb_t),1,ixb_fp);
  504.     fwrite(&user,sizeof(user_t),1,tmp_fp);
  505.     }
  506. fprintf(stderr,"\n");
  507. fcloseall();
  508. remove("SMM.DAB");
  509. rename("SMM.TMP","SMM.DAB");
  510.  
  511. printf("Synchronet Match Maker Statistics\n");
  512. printf("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n");
  513. printf("\n");
  514. printf("%-25s         : %lu\n","Total",users);
  515. printf("%-25s         : %lu\n","Photos",photos);
  516. printf("%-25s         : %lu\n","Networked",networked);
  517. // if(male_straight)
  518.     printf("%-25s (%4.1f%%) : %lu\n","Sex: male (hetero)"
  519.         ,(((float)male_straight/users)*100.0),male_straight);
  520. // if(male_gay)
  521.     printf("%-25s (%4.1f%%) : %lu\n","Sex: male (gay)"
  522.         ,(((float)male_gay/users)*100.0),male_gay);
  523. // if(male_bi)
  524.     printf("%-25s (%4.1f%%) : %lu\n","Sex: male (bi)"
  525.         ,(((float)male_bi/users)*100.0),male_bi);
  526. // if(female_straight)
  527.     printf("%-25s (%4.1f%%) : %lu\n","Sex: female (hetero)"
  528.         ,(((float)female_straight/users)*100.0),female_straight);
  529. // if(female_gay)
  530.     printf("%-25s (%4.1f%%) : %lu\n","Sex: female (gay)"
  531.         ,(((float)female_gay/users)*100.0),female_gay);
  532. // if(female_bi)
  533.     printf("%-25s (%4.1f%%) : %lu\n","Sex: female (bi)"
  534.         ,(((float)female_bi/users)*100.0),female_bi);
  535. // if(age12)
  536.     printf("%-25s (%4.1f%%) : %lu\n","Age: 12 and younger"
  537.         ,(((float)age12/users)*100.0),age12);
  538. // if(age15)
  539.     printf("%-25s (%4.1f%%) : %lu\n","Age: 13 to 15 years old"
  540.         ,(((float)age15/users)*100.0),age15);
  541. // if(age20)
  542.     printf("%-25s (%4.1f%%) : %lu\n","Age: 16 to 20 years old"
  543.         ,(((float)age20/users)*100.0),age20);
  544. // if(age25)
  545.     printf("%-25s (%4.1f%%) : %lu\n","Age: 21 to 25 years old"
  546.         ,(((float)age25/users)*100.0),age25);
  547. // if(age30)
  548.     printf("%-25s (%4.1f%%) : %lu\n","Age: 26 to 30 years old"
  549.         ,(((float)age30/users)*100.0),age30);
  550. // if(age35)
  551.     printf("%-25s (%4.1f%%) : %lu\n","Age: 31 to 35 years old"
  552.         ,(((float)age35/users)*100.0),age35);
  553. // if(age40)
  554.     printf("%-25s (%4.1f%%) : %lu\n","Age: 36 to 40 years old"
  555.         ,(((float)age40/users)*100.0),age40);
  556. // if(age45)
  557.     printf("%-25s (%4.1f%%) : %lu\n","Age: 41 to 45 years old"
  558.         ,(((float)age45/users)*100.0),age45);
  559. // if(age50)
  560.     printf("%-25s (%4.1f%%) : %lu\n","Age: 46 to 50 years old"
  561.         ,(((float)age50/users)*100.0),age50);
  562. // if(age55)
  563.     printf("%-25s (%4.1f%%) : %lu\n","Age: 51 to 55 years old"
  564.         ,(((float)age55/users)*100.0),age55);
  565. // if(age60)
  566.     printf("%-25s (%4.1f%%) : %lu\n","Age: 56 to 60 years old"
  567.         ,(((float)age60/users)*100.0),age60);
  568. // if(age65)
  569.     printf("%-25s (%4.1f%%) : %lu\n","Age: 61 to 65 years old"
  570.         ,(((float)age65/users)*100.0),age65);
  571. // if(age70)
  572.     printf("%-25s (%4.1f%%) : %lu\n","Age: 66 to 70 years old"
  573.         ,(((float)age70/users)*100.0),age70);
  574. // if(age71)
  575.     printf("%-25s (%4.1f%%) : %lu\n","Age: 71 and older"
  576.         ,(((float)age71/users)*100.0),age71);
  577. // if(hair_blonde)
  578.     printf("%-25s (%4.1f%%) : %lu\n","Hair: blonde"
  579.         ,(((float)hair_blonde/users)*100.0),hair_blonde);
  580. // if(hair_brown)
  581.     printf("%-25s (%4.1f%%) : %lu\n","Hair: brown"
  582.         ,(((float)hair_brown/users)*100.0),hair_brown);
  583. // if(hair_black)
  584.     printf("%-25s (%4.1f%%) : %lu\n","Hair: black"
  585.         ,(((float)hair_black/users)*100.0),hair_black);
  586. // if(hair_red)
  587.     printf("%-25s (%4.1f%%) : %lu\n","Hair: red"
  588.         ,(((float)hair_red/users)*100.0),hair_red);
  589. // if(hair_grey)
  590.     printf("%-25s (%4.1f%%) : %lu\n","Hair: grey"
  591.         ,(((float)hair_grey/users)*100.0),hair_grey);
  592. // if(hair_other)
  593.     printf("%-25s (%4.1f%%) : %lu\n","Hair: other"
  594.         ,(((float)hair_other/users)*100.0),hair_other);
  595. // if(eyes_blue)
  596.     printf("%-25s (%4.1f%%) : %lu\n","Eyes: blue"
  597.         ,(((float)eyes_blue/users)*100.0),eyes_blue);
  598. // if(eyes_brown)
  599.     printf("%-25s (%4.1f%%) : %lu\n","Eyes: brown"
  600.         ,(((float)eyes_brown/users)*100.0),eyes_brown);
  601. // if(eyes_green)
  602.     printf("%-25s (%4.1f%%) : %lu\n","Eyes: green"
  603.         ,(((float)eyes_green/users)*100.0),eyes_green);
  604. // if(eyes_hazel)
  605.     printf("%-25s (%4.1f%%) : %lu\n","Eyes: hazel"
  606.         ,(((float)eyes_hazel/users)*100.0),eyes_hazel);
  607. // if(eyes_other)
  608.     printf("%-25s (%4.1f%%) : %lu\n","Eyes: other"
  609.         ,(((float)eyes_other/users)*100.0),eyes_other);
  610. // if(race_white)
  611.     printf("%-25s (%4.1f%%) : %lu\n","Race: white"
  612.         ,(((float)race_white/users)*100.0),race_white);
  613. // if(race_black)
  614.     printf("%-25s (%4.1f%%) : %lu\n","Race: black"
  615.         ,(((float)race_black/users)*100.0),race_black);
  616. // if(race_asian)
  617.     printf("%-25s (%4.1f%%) : %lu\n","Race: asian"
  618.         ,(((float)race_asian/users)*100.0),race_asian);
  619. // if(race_amerindian)
  620.     printf("%-25s (%4.1f%%) : %lu\n","Race: amerindian"
  621.         ,(((float)race_amerindian/users)*100.0),race_amerindian);
  622. // if(race_mideastern)
  623.     printf("%-25s (%4.1f%%) : %lu\n","Race: mideastern"
  624.         ,(((float)race_mideastern/users)*100.0),race_mideastern);
  625. // if(race_hispanic)
  626.     printf("%-25s (%4.1f%%) : %lu\n","Race: hispanic"
  627.         ,(((float)race_hispanic/users)*100.0),race_hispanic);
  628. // if(race_other)
  629.     printf("%-25s (%4.1f%%) : %lu\n","Race: other"
  630.         ,(((float)race_other/users)*100.0),race_other);
  631. // if(marital_single)
  632.     printf("%-25s (%4.1f%%) : %lu\n","Marital: single"
  633.         ,(((float)marital_single/users)*100.0),marital_single);
  634. // if(marital_married)
  635.     printf("%-25s (%4.1f%%) : %lu\n","Marital: married"
  636.         ,(((float)marital_married/users)*100.0),marital_married);
  637. // if(marital_divorced)
  638.     printf("%-25s (%4.1f%%) : %lu\n","Marital: divorced"
  639.         ,(((float)marital_divorced/users)*100.0),marital_divorced);
  640. // if(marital_widowed)
  641.     printf("%-25s (%4.1f%%) : %lu\n","Marital: widowed"
  642.         ,(((float)marital_widowed/users)*100.0),marital_widowed);
  643. // if(marital_other)
  644.     printf("%-25s (%4.1f%%) : %lu\n","Marital: other"
  645.         ,(((float)marital_other/users)*100.0),marital_other);
  646. // if(zodiac_aries)
  647.     printf("%-25s (%4.1f%%) : %lu\n","Zodiac: aries"
  648.         ,(((float)zodiac_aries/users)*100.0),zodiac_aries);
  649. // if(zodiac_taurus)
  650.     printf("%-25s (%4.1f%%) : %lu\n","Zodiac: taurus"
  651.         ,(((float)zodiac_taurus/users)*100.0),zodiac_taurus);
  652. // if(zodiac_gemini)
  653.     printf("%-25s (%4.1f%%) : %lu\n","Zodiac: gemini"
  654.         ,(((float)zodiac_gemini/users)*100.0),zodiac_gemini);
  655. // if(zodiac_cancer)
  656.     printf("%-25s (%4.1f%%) : %lu\n","Zodiac: cancer"
  657.         ,(((float)zodiac_cancer/users)*100.0),zodiac_cancer);
  658. // if(zodiac_leo)
  659.     printf("%-25s (%4.1f%%) : %lu\n","Zodiac: leo"
  660.         ,(((float)zodiac_leo/users)*100.0),zodiac_leo);
  661. // if(zodiac_virgo)
  662.     printf("%-25s (%4.1f%%) : %lu\n","Zodiac: virgo"
  663.         ,(((float)zodiac_virgo/users)*100.0),zodiac_virgo);
  664. // if(zodiac_libra)
  665.     printf("%-25s (%4.1f%%) : %lu\n","Zodiac: libra"
  666.         ,(((float)zodiac_libra/users)*100.0),zodiac_libra);
  667. // if(zodiac_scorpio)
  668.     printf("%-25s (%4.1f%%) : %lu\n","Zodiac: scorpio"
  669.         ,(((float)zodiac_scorpio/users)*100.0),zodiac_scorpio);
  670. // if(zodiac_sagittarius)
  671.     printf("%-25s (%4.1f%%) : %lu\n","Zodiac: sagittarius"
  672.         ,(((float)zodiac_sagittarius/users)*100.0),zodiac_sagittarius);
  673. // if(zodiac_capricorn)
  674.     printf("%-25s (%4.1f%%) : %lu\n","Zodiac: capricorn"
  675.         ,(((float)zodiac_capricorn/users)*100.0),zodiac_capricorn);
  676. // if(zodiac_aquarius)
  677.     printf("%-25s (%4.1f%%) : %lu\n","Zodiac: aquarius"
  678.         ,(((float)zodiac_aquarius/users)*100.0),zodiac_aquarius);
  679. // if(zodiac_pisces)
  680.     printf("%-25s (%4.1f%%) : %lu\n","Zodiac: pisces"
  681.         ,(((float)zodiac_pisces/users)*100.0),zodiac_pisces);
  682.  
  683. if(!max_wall)
  684.     return(0);
  685.  
  686. if((file=open("WALL.DAB",O_RDWR|O_BINARY|O_DENYNONE))==-1
  687.     || (dab_fp=fdopen(file,"r+b"))==NULL) {
  688.     printf("Error opening WALL.DAB\n");
  689.     exit(1); }
  690.  
  691. if((file=open("WALL.TMP",O_WRONLY|O_CREAT|O_TRUNC|O_BINARY|O_DENYALL
  692.     ,S_IWRITE|S_IREAD))==-1
  693.     || (tmp_fp=fdopen(file,"r+b"))==NULL) {
  694.     printf("Error opening WALL.TMP\n");
  695.     exit(1); }
  696.  
  697. fprintf(stderr,"Reading wall data...");
  698. rewind(dab_fp);
  699. while(!feof(dab_fp)) {
  700.     if(!fread(&wall,sizeof(wall_t),1,dab_fp))
  701.         break;
  702.     if((now-wall.imported)/(24UL*60UL*60UL)<=max_wall)
  703.         fwrite(&wall,sizeof(wall_t),1,tmp_fp); }
  704.  
  705. fprintf(stderr,"\n");
  706. fcloseall();
  707. remove("WALL.DAB");
  708. rename("WALL.TMP","WALL.DAB");
  709.  
  710. return(0);
  711. }
  712.