Annotation of sbbs/sbbs2/smb/121a/qwk2smb.c, revision 1.1.1.1

1.1       root        1: /* QWK2SMB.C */
                      2: 
                      3: /* Converts QWK packet to to SMB formatted message bases */
                      4: 
                      5: /* The intention of this source code is an example of how to use the SMBLIB */
                      6: /* library functions to access an SMB format message base.                                     */
                      7: 
                      8: /* This program and source code are freeware. May be used in part or whole     */
                      9: /* for any purpose without consent or notification of Digital Dynamics.        */
                     10: 
                     11: /* Digital Dynamics does request that developers that release products that */
                     12: /* support the SMB format notify Digital Dynamics so the implementation        */
                     13: /* and contact chapters in the technical specification may be updated.         */
                     14: 
                     15: #include "smblib.h"
                     16: #include "crc32.h"
                     17: #include <dos.h>
                     18: 
                     19: char sbbs[128];
                     20: 
                     21: /****************************************************************************/
                     22: /* Updates 16-bit "rcrc" with character 'ch'                                */
                     23: /****************************************************************************/
                     24: void ucrc16(uchar ch, ushort *rcrc) {
                     25:        ushort i, cy;
                     26:     uchar nch=ch;
                     27:  
                     28: for (i=0; i<8; i++) {
                     29:     cy=*rcrc & 0x8000;
                     30:     *rcrc<<=1;
                     31:     if (nch & 0x80) *rcrc |= 1;
                     32:     nch<<=1;
                     33:     if (cy) *rcrc ^= 0x1021; }
                     34: }
                     35: 
                     36: /****************************************************************************/
                     37: /* Returns 16-crc of string (not counting terminating NULL)                            */
                     38: /****************************************************************************/
                     39: ushort crc16(char *str)
                     40: {
                     41:        int     i=0;
                     42:        ushort  crc=0;
                     43: 
                     44: ucrc16(0,&crc);
                     45: while(str[i])
                     46:        ucrc16(str[i++],&crc);
                     47: ucrc16(0,&crc);
                     48: ucrc16(0,&crc);
                     49: return(crc);
                     50: }
                     51: 
                     52: 
                     53: /****************************************************************************/
                     54: /* Truncates white-space chars off end of 'str' and terminates at first tab */
                     55: /****************************************************************************/
                     56: void truncsp(char *str)
                     57: {
                     58:        char c;
                     59: 
                     60: str[strcspn(str,"\t")]=0;
                     61: c=strlen(str);
                     62: while(c && (uchar)str[c-1]<=' ') c--;
                     63: str[c]=0;
                     64: }
                     65: 
                     66: /****************************************************************************/
                     67: /* Converts an ASCII Hex string into an ulong                       */
                     68: /****************************************************************************/
                     69: ulong ahtoul(char *str)
                     70: {
                     71:        ulong l,val=0;
                     72: 
                     73: while((l=(*str++)|0x20)!=0x20)
                     74:        val=(l&0xf)+(l>>6&1)*9+val*16;
                     75: return(val);
                     76: }
                     77: 
                     78: /****************************************************************************/
                     79: /* Returns the length of the file in 'filespec'                             */
                     80: /****************************************************************************/
                     81: long flength(char *filespec)
                     82: {
                     83:     struct ffblk f;
                     84: 
                     85: if(findfirst(filespec,&f,0)==0)
                     86:     return(f.ff_fsize);
                     87: return(-1L);
                     88: }
                     89: 
                     90: /****************************************************************************/
                     91: /* Returns the FidoNet address kept in str as ASCII.                        */
                     92: /****************************************************************************/
                     93: fidoaddr_t atofaddr(char *str)
                     94: {
                     95:     char *p;
                     96:        fidoaddr_t addr;
                     97: 
                     98: addr.zone=addr.net=addr.node=addr.point=0;
                     99: if((p=strchr(str,':'))!=NULL) {
                    100:        addr.zone=atoi(str);
                    101:        addr.net=atoi(p+1); }
                    102: else {
                    103:        addr.zone=1;
                    104:        addr.net=atoi(str); }
                    105: if(!addr.zone)                         /* no such thing as zone 0 */
                    106:        addr.zone=1;
                    107: if((p=strchr(str,'/'))!=NULL)
                    108:     addr.node=atoi(p+1);
                    109: else {
                    110:        addr.net=1;
                    111:        addr.node=atoi(str); }
                    112: if((p=strchr(str,'.'))!=NULL)
                    113:     addr.point=atoi(p+1);
                    114: return(addr);
                    115: }
                    116: 
                    117: 
                    118: int main(int argc, char **argv)
                    119: {
                    120:        uchar   *p,str[128],from[128],to[128],subj[128],block[128],*buf;
                    121:        ushort  xlat;
                    122:        ushort  i,j,k,msgs,total;
                    123:        ulong   l,m,length,size,crc;
                    124:        FILE    *qwk;
                    125:        struct  date date;
                    126:        struct  time curtime;
                    127:        smbmsg_t        msg;
                    128:        smbstatus_t status;
                    129: 
                    130: if(argc<2) {
                    131:        printf("usage: qwk2smb <qwk_dir>\r\n");
                    132:        exit(1); }
                    133: 
                    134: sprintf(str,"%s\\MESSAGES.DAT",argv[1]);
                    135: if((qwk=fopen(str,"rb"))==NULL) {
                    136:        printf("error opening %s\n",str);
                    137:        exit(1); }
                    138: 
                    139: size=filelength(fileno(qwk));
                    140: smb_file[0]=0;
                    141: 
                    142: for(l=128,i=1,msgs=total=1;l<size;l+=i*128) {
                    143:        fseek(qwk,l,SEEK_SET);
                    144:        if(!fread(block,1,128,qwk))
                    145:                break;
                    146:        i=atoi(block+116);      /* i = number of 128 byte records */
                    147:        if(i<2) {
                    148:                i=1;
                    149:                continue; }
                    150: 
                    151:        j=(ushort)block[123]|(((ushort)block[124])<<8);  /* conference number */
                    152: 
                    153:        if(strcmp(smb_file,itoa(j,str,10))) {            /* changed conference */
                    154:                fclose(sdt_fp);
                    155:                fclose(shd_fp);
                    156:                fclose(sid_fp);
                    157:                strcpy(smb_file,str);
                    158:                printf("\nConference #%s\n",str);
                    159:                msgs=1;
                    160:                k=smb_open(10);
                    161:                if(k) {
                    162:                        printf("smb_open returned %d\n",k);
                    163:                        exit(1); }
                    164:                if(!filelength(fileno(shd_fp)))                 /* new conference */
                    165:                        smb_create(2000,2000,0,0,10); }
                    166: 
                    167:        smb_getstatus(&status);           // Initialized for first call to smb_addcrc()
                    168: 
                    169:        printf("%u (total=%u)\r",msgs,total);
                    170: 
                    171:        /*****************************/
                    172:        /* Initialize the SMB header */
                    173:        /*****************************/
                    174: 
                    175:        memset(&msg,0,sizeof(smbmsg_t));
                    176:        memcpy(msg.hdr.id,"SHD\x1a",4);
                    177:        msg.hdr.version=SMB_VERSION;
                    178: 
                    179:        /**************************/
                    180:        /* Convert the QWK header */
                    181:        /**************************/
                    182: 
                    183:        if(block[0]=='*' || block[0]=='+')
                    184:                msg.idx.attr|=MSG_PRIVATE;
                    185:        if(block[0]=='*' || block[0]=='-' || block[0]=='`')
                    186:                msg.idx.attr|=MSG_READ;
                    187:     msg.hdr.attr=msg.idx.attr;
                    188: 
                    189:        date.da_mon=((block[8]&0xf)*10)+(block[9]&0xf);
                    190:        date.da_day=((block[11]&0xf)*10)+(block[12]&0xf);
                    191:        date.da_year=((block[14]&0xf)*10)+(block[15]&0xf)+1900;
                    192:        curtime.ti_hour=((block[16]&0xf)*10)+(block[17]&0xf);
                    193:        curtime.ti_min=((block[19]&0xf)*10)+(block[20]&0xf);
                    194:        curtime.ti_sec=0;
                    195:        msg.hdr.when_written.time=dostounix(&date,&curtime);
                    196:        msg.hdr.when_written.zone=PST;           /* set to local time zone */
                    197:        msg.hdr.when_imported.time=time(NULL);
                    198:        msg.hdr.when_imported.zone=PST;          /* set to local time zone */
                    199: 
                    200:        sprintf(to,"%25.25s",block+21);     /* To user */
                    201:     truncsp(to);
                    202:     smb_hfield(&msg,RECIPIENT,strlen(to),to);
                    203:     strlwr(to);
                    204:     msg.idx.to=crc16(to);
                    205: 
                    206:        sprintf(from,"%25.25s",block+46);   /* From user */
                    207:     truncsp(from);
                    208:     smb_hfield(&msg,SENDER,strlen(from),from);
                    209:     strlwr(from);
                    210:     msg.idx.from=crc16(from);
                    211: 
                    212:        sprintf(subj,"%25.25s",block+71);   /* Subject */
                    213:        truncsp(subj);
                    214:        smb_hfield(&msg,SUBJECT,strlen(subj),subj);
                    215:        strlwr(subj);
                    216:     msg.idx.subj=crc16(subj);
                    217: 
                    218:        /********************************/
                    219:        /* Convert the QWK message text */
                    220:        /********************************/
                    221: 
                    222:        length=0;
                    223:        if((buf=MALLOC((i-1)*128*2))==NULL) {
                    224:                printf("memory allocation error\n");
                    225:                exit(1); }
                    226:        for(j=1;j<i;j++) {
                    227:                if(!fread(block,1,128,qwk))
                    228:                        break;
                    229:                for(k=0;k<128;k++) {
                    230:                        if(block[k]==0)
                    231:                                continue;
                    232:                        if(block[k]==0xE3) {       /* expand 0xe3 to crlf */
                    233:                                buf[length++]=CR;
                    234:                                buf[length++]=LF;
                    235:                                continue; }
                    236:                        buf[length++]=block[k]; } }
                    237: 
                    238:        while(length && buf[length-1]<=SP) length--; /* remove trailing garbage */
                    239: 
                    240:        /*****************/
                    241:        /* Calculate CRC */
                    242:        /*****************/
                    243: 
                    244:        crc=0xffffffffUL;
                    245:        for(m=0;m<length;m++)
                    246:                crc=ucrc32(buf[m],crc);
                    247:        crc=~crc;
                    248: 
                    249:        /*******************/
                    250:        /* Check for dupes */
                    251:        /*******************/
                    252: 
                    253:        j=smb_addcrc(status.max_crcs,crc,10);
                    254:     if(j) {
                    255:         if(j==1) {
                    256:             printf("\nDuplicate message\n");
                    257:             smb_freemsgmem(msg);
                    258:                        FREE(buf);
                    259:             continue; }
                    260:         printf("smb_addcrc returned %d\n",j);
                    261:         exit(1); }
                    262: 
                    263:        /*************************************/
                    264:        /* Write SMB message header and text */
                    265:        /*************************************/
                    266: 
                    267:        length+=2;      /* for translation string */
                    268: 
                    269:        if(smb_open_da(10)) {
                    270:                printf("error opening %s.SDA\n",smb_file);
                    271:                exit(1); }
                    272:        msg.hdr.offset=smb_fallocdat(length,1);
                    273:        fclose(sda_fp);
                    274:        if(msg.hdr.offset && msg.hdr.offset<1L) {
                    275:                printf("error %ld allocating blocks\r\n",msg.hdr.offset);
                    276:                exit(1); }
                    277:        fseek(sdt_fp,msg.hdr.offset,SEEK_SET);
                    278:     xlat=XLAT_NONE;
                    279:     fwrite(&xlat,2,1,sdt_fp);
                    280:        fwrite(buf,length,1,sdt_fp);
                    281:        fflush(sdt_fp);
                    282: 
                    283:        smb_dfield(&msg,TEXT_BODY,length);
                    284: 
                    285:        k=smb_addmsghdr(&msg,&status,1,10);
                    286:        if(k) {
                    287:                printf("smb_addmsghdr returned %d\n",k);
                    288:                exit(1); }
                    289:        smb_freemsgmem(msg);
                    290:        FREE(buf);
                    291:        msgs++;
                    292:        total++; }
                    293: 
                    294: return(0);
                    295: }
                    296: 

unix.superglobalmegacorp.com

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