home *** CD-ROM | disk | FTP | other *** search
- /* dir.c */
- #include <libraries/dos.h>
- #include <exec/memory.h>
- #include "mb.h"
- /*
- * Directory access routines.
- */
-
-
- /*
- * A directory item looks like this:
- struct FileInfoBlock {
- LONG fib_DiskKey;
- LONG fib_DirEntryType;
- char fib_FileName[108];
- LONG fib_Protection;
- LONG fib_EntryType;
- LONG fib_Size;
- LONG fib_NumBlocks;
- struct DateStamp fib_Date;
- char fib_Comment[80];
- char padding[36];
- };
- */
-
- typedef struct FileInfoBlock FCB;
- extern char tmpstr[];
- extern short debug;
- static int olddta;
- static FCB *fcb = 0;
- static struct InfoData *ID = 0L;
- char wcstring[100];
-
- /*
- * Open directory, return first item.
- */
- diropen(cp, p, dirdef)
- UBYTE *cp;
- DIRDEF *dirdef;
- DIRENT *p;
- {
- long result;
- if(fcb == 0) {
- fcb = (FCB *)AllocMem((long)sizeof(*fcb),
- (long)MEMF_PUBLIC|MEMF_CLEAR);
- }
- if(ID == 0) {
- ID = (struct InfoData *)AllocMem((long)sizeof(*ID),
- (long)MEMF_PUBLIC|MEMF_CLEAR);
- }
-
- /*
- * Get the first directory entry.
- */
- dirdef->lock = Lock(cp,ACCESS_READ);
- if(dirdef->lock == 0L) {
- p->size = -1;
- return (false);
- }
- if(Info(dirdef->lock,ID) == 0L) {
- /* If Info fails then the named file/device is NOT a disk */
- dirdef->size = 0L;
- dirdef->free = 0L;
- return(false);
- }
- else {
- dirdef->size =
- ((ID->id_BytesPerBlock*ID->id_NumBlocksUsed + 1023L) / 1024L);
- dirdef->free =
- ((ID->id_BytesPerBlock * ID->id_NumBlocks + 1023L) / 1024L)
- - dirdef->size;
- }
- /* Examine this name to find out what it is - it MUST be a directory */
- if((result = Examine(dirdef->lock,fcb)) == 0L) {
- UnLock(dirdef->lock);
- p->size = -1;
- return (false);
- }
- if(fcb->fib_DirEntryType < 0) { /* It's a file! That's WRONG! */
- UnLock(dirdef->lock);
- p->size = -1;
- return (false);
- }
- if(dirnext(p,dirdef))return(false);
- if(dodir(p)) return (true);
- return (false);
- }
- freefcb()
- {
- if(fcb)FreeMem(fcb,(long)sizeof(*fcb));
- if(ID)FreeMem(ID,(long)sizeof(*ID));
- }
- /*
- * Return first and succeeding filenames in the directory.
- * And if a wildcard is specified only return the matching
- * names.
- */
-
- dirnext(p, dirdef)
- DIRENT *p;
- DIRDEF *dirdef;
- {
- /* search for next filename in the directory */
- while(true) {
- if(ExNext(dirdef->lock,fcb) == 0L) {
- p->size = -1;
- UnLock(dirdef->lock);
- return(1);
- }
- if (dodir(p)) {
- return(0);
- }
- }
- }
-
- dodir(p)
- DIRENT *p;
- {
- /* wcmatch checks wcstring against fcb->fib_FileName
- If the wildcard is null then everything matches it and
- wcmatch returns a true, otherwise it returns true only
- if the wcstring and filename match
- */
- if(wcmatch(&fcb->fib_FileName[0],&wcstring[0]) == 0)return(false);
- strcpy(p->name,&fcb->fib_FileName[0]);
- if(fcb->fib_DirEntryType >= 0) { /*It's a directory */
- if(!match(p->name, "/")) {
- return (false);
- }
- if(port->mode & (local | sysop)) {
- strcat(p->name, "/");
- }
- else {
- return (false);
- }
- }
- /* return the size in Kb rounded up */
- p->size = (fcb->fib_Size+01777)>>10;
- return (true);
- }
-
- /*
- * Modified form of getdir from original mbfile.c
- * The amiga searches directories for wildcards in
- * a different way than does the IBM. SO set it up
- * for a wildcard match for the amiga.
- *
- */
- extern DIRPATH *dphd;
- DIRPATH *setdir(p)
- char *p;
- {
- register DIRPATH *dp;
- register char *cp,*pp;
- cp = p;
- pp = &wcstring[0];
- *pp = 0;
- for(dp = dphd; dp isnt NULL; dp = dp->next)
- if (dp->id is port->opt2) {
- strcpy(port->line, dp->path);
- while(*cp)*pp++ = *cp++;
- *pp = 0;
- return dp;
- }
- port->msg = mndir;
- return NULL;
- }
- /* Check filename in *a against a possibly null wildcard string in *b */
- wcmatch(a,b)
- char *a,*b;
- {
- register char *p,*q;
- p = a;
- q = b;
- /* If the wildcard is null then everything matches */
- if(*q == 0)return(1);
- if(*q == '*') {
- /* Leading wildcard * in the pattern */
- while(*p)p++;
- while(*q)q++;
- p--;
- q--;
- while(*q != '*') {
- if(toupper(*p) == toupper(*q)) {
- p--;
- q--;
- continue;
- }
- break;
- }
- if(*q == '*')return(1);
- return(0);
- }
- while(*p && *q && (*q != '*')) {
- if(toupper(*p) == toupper(*q)) {
- p++;
- q++;
- continue;
- }
- break;
- }
- if((*p == 0) && (*q == 0))return(1);
- if(*q == '*')return(1);
- return(0);
- }
- /* Check call or @bbs in *a against a wildcard string in *b
- Both are ln_call characters long and have trailing spaces added
- */
-
- wmatch(a,b)
- char *a,*b;
- {
- register char *p,*q;
- register short i;
- char inname[ln_call+1],wildc[ln_call+1];
-
- /* copy the two input strings into temporary storage, removing the
- trailing blanks. This routine is obviously a slightly modified
- form of the directory wcmatch routine.
- The copy also forces both strings to upper case to save having
- to do it later.
- */
- p = a;
- q = inname;
- for(i = 0;i<ln_call;i++) {
- if(*p == ' ')break;
- *q++ = toupper(*p++);
- }
- *q++ = 0;
- p = b;
- q = wildc;
- for(i = 0;i<ln_call;i++) {
- if(*p == ' ')break;
- *q++ = toupper(*p++);
- }
- *q++ = 0;
- p = inname;
- q = wildc;
- /* If the wildcard is null then everything matches */
- if(*q == 0)return(1);
- if(*q == '*') {
- /* Leading wildcard * in the pattern */
- while(*p)p++;
- while(*q)q++;
- p--;
- q--;
- while(*q != '*') {
- if(*p == *q) {
- p--;
- q--;
- continue;
- }
- break;
- }
- if(*q == '*')return(1);
- return(0);
- }
- while(*p && *q && (*q != '*')) {
- if(*p == *q) {
- p++;
- q++;
- continue;
- }
- break;
- }
- if((*p == 0) && (*q == 0))return(1);
- if(*q == '*')return(1);
- return(0);
- }
- /* Check title in *a against a quoted string in *b */
- /* If the string occurs anywhere in the title then
- return non-null.
- */
- umatch(a,b)
- char *a,*b;
- {
- register char *p,*q,*r,*s;
- short i,j;
- if((i = strlen(a)) > 79) {
- i = 79;
- *(a+79) = 0;
- }
- if((j = strlen(b)) > 79) {
- j = 79;
- *(b+79) = 0;
- }
- j -= 2; /* Don't count the quotes */
- if(j > i)return(0); /* Quoted string is longer than title */
- r = a + i - j;
- for(p = a;p <= r;p++) {
- q = p;
- s = b+1; /* Skip the quote */
- while(*s && (*s != '"')) {
- if(toupper(*q) != *s)break; /* The string is already upper */
- q++;
- s++;
- }
- if((*s == '"') || (*s == 0))return(1);
- }
- return(0);
- }
- kill_list()
- {
- register int from,to,i;
- register PORTS *p;
- p = port;
- ioport(cport);
- if(!num(port->fld[1]) || !num(port->fld[2])) {
- port->msg = mwhat;
- ioport(p);
- return;
- }
- from = atoi(port->fld[1]);
- to = atoi(port->fld[2]);
- if((from < 1) || (to < 1) || (from >= to)) {
- port->msg = mwhat;
- ioport(p);
- return;
- }
- sprintf(tmpstr,"Delete messages from #%d to #%d\n",from,to);
- outstr(tmpstr);
- if(sure())return;
- /* Search forwards through the file to find the first message number
- The messages are more likely to be near the front of the file than
- the end. The end of the file has more recent messages.
- However, a binary search would be the best strategy and I'll put it in
- here when I have time.
- */
- check_mail();
- unlock_mail();
- for(i = 1; i <= mfhs->last ; i++) {
- read_rec(mfl, i, (char *)port->mmhs);
- /*
- sprintf(tmpstr,"rec#%d = msg#%d\n",i,port->mmhs->number);
- ttputs(tmpstr);
- */
- if (port->mmhs->number >= from) break;
- }
- if((port->mmhs->number < from) || (port->mmhs->number > to)) {
- outstr("No messages in the specified range\n");
- return;
- }
- /* This re-reads the very first record but the loop is easier to
- write this way.
- Delete messages within the specified range.
- */
- for( ; i <= mfhs->last ; i++) {
- read_rec(mfl, i, (char *)port->mmhs);
- if (port->mmhs->number > to) break;
-
- /* Is it already dead? */
- if(port->mmhs->stat & m_kill) continue;
-
- /* Don't kill traffic this way. They must be done individually */
- if(port->mmhs->type is 'T')continue;
-
- sprintf(tmpstr,"%d",port->mmhs->number);
- outstr(tmpstr);
- outstr(" - Killed\n");
-
- port->mmhs->stat setbit m_kill;
- write_rec(mfl, i, (char *)port->mmhs);
- makehdr2();
-
- }
- sprintf(tmpstr,"from %d to %d",from,to);
- log('M', 'K', 'L', tmpstr);
- ioport(p);
- port->msg = mdone;
- titles();
- }
-
-
- char reject[TOT_REJECT][3][ln_call];
- short num_reject = 0;
-
- get_reject()
- {
- /* This routine MUST be called before the window is opened */
- FILE *fp;
- register char *p,*q;
- register int fc,i;
- if((fp = fopen("reject.btn","r")) == NULL)return;
- while(fgets(&tmpstr[0],80,fp) != NULL) {
- p = tmpstr;
- if(*p == '\n')continue;
- fc = 0;
- while(1) {
- switch(*p) {
- case '<': /* FROM field */
- p++;
- fc++;
- q = &reject[num_reject][2][0];
- pcall(q,p);
- break;
- case '@': /* AT (BBS) field */
- p++;
- fc++;
- q = &reject[num_reject][1][0];
- pcall(q,p);
- break;
- case '>': /* TO field */
- p++;
- fc++;
- q = &reject[num_reject][0][0];
- pcall(q,p);
- break;
- }
- while((*p != ' ') && (*p != '\n') && *p)p++;
- if((*p == '\n') || (*p == 0))break;
- while(*p == ' ')p++;
- }
- if(fc == 0) { /* No fields found .. don't use it */
- reject[num_reject][0][0] = 0;
- reject[num_reject][1][0] = 0;
- reject[num_reject][2][0] = 0;
- continue;
- }
- if(num_reject++ > TOT_REJECT-1)break;
- }
- fclose(fp);
- if(num_reject > TOT_REJECT-1)num_reject = TOT_REJECT-1;
- printf("\nReject.btn list\n");
- /* This loop does not only prepare the reject list for printing.
- It also converts the fields to upper case. So do not delete
- the entire loop
- */
-
- for(fc = 0;fc < num_reject;fc++) {
- for(i=0;i<3;i++) {
- p = tmpstr;
- *p = 0;
- q = &reject[fc][i][0];
- while(*q && (*q != ' ') && (q < &reject[fc][i][ln_call])) {
- *q = toupper(*q);
- *p++ = *q++;
- *p = 0;
- }
- printf("%c%s ",">@<"[i],&tmpstr[0]);
- }
- printf("\n");
- }
- printf("\n");
- }
-
- test_reject()
- {
- register short i;
- /* Allow sysop to send them out, but reject them from anyone else? */
- /* How about rejecting only when forwarding? */
- if(port->mode == local)return(0);
- for(i=0;i<num_reject;i++) {
- if(reject[i][0][0]) {
- if(!matchn(&reject[i][0][0],port->mmhs->to,ln_call))continue;
- }
- if(reject[i][1][0]) {
- if(!matchn(&reject[i][1][0],port->mmhs->bbs,ln_call))continue;
- }
- if(reject[i][2][0]) {
- if(!matchn(&reject[i][2][0],port->mmhs->from,ln_call))continue;
- }
- return(1);
- }
- return(0);
- }
-