⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 vdelivermail.c

📁 相当优秀的 UNIX 进程管理工具
💻 C
📖 第 1 页 / 共 3 页
字号:
    }#ifdef MAKE_SEEKABLE    if (!Seekable(0))        MakeSeekable(stdin);#endif    lseek(0,0L,SEEK_SET);    while(fgets(loop_buf,sizeof(loop_buf),stdin)!=NULL){        /* if we find the line, return error (looping) */        if (strncmp(loop_buf, "Delivered-To: ", 14) == 0 &&            is_loop_match(loop_buf, address)==1 ) {            /* return the loop found */            return(1);            /* check for the start of the body, we only need            * to check the headers.             */        } else {            /* walk through the charaters in the body */            for(i=0,found=0;loop_buf[i]!=0&&found==0;++i){                switch(loop_buf[i]){                    /* skip blank spaces and new lines */                    case ' ':                    case '\n':                    case '\t':                    case '\r':                    break;                    /* found a non blank, so we are still                    * in the headers                    */                    default:                            /* set the found non blank char flag */                        found = 1;                        break;                }            }            /* if the line only had blanks, then it is the             * delimiting line between the headers and the             * body. We don't need to check the body for             * the duplicate Delivered-To: line. Hence, we             * are done with our search and can return the             * looping not found value            */            if ( found == 0 ) {                /* return not found looping message value */                return(0);            }        }    }    /* if we get here then the there is either no body      * or the logic above failed and we scanned     * the whole email, headers and body.      */    return(0);}/*  * Get the size of the email message  * return the size  */off_t get_message_size(){ ssize_t message_size; ssize_t bytes;#ifdef MAKE_SEEKABLE    if (!Seekable(0))        MakeSeekable(stdin);#endif    if ( lseek(0, 0L,SEEK_SET) < 0 ) {        printf("lseek error %d\n", errno);        return(-1);    }    message_size = 0;    while((bytes=read(0,msgbuf,MSG_BUF_SIZE))>0) {        message_size += bytes;    }    return(message_size);}/* * check for locked account * deliver to .qmail file if any * deliver to user if no .qmail file */void checkuser() { struct stat mystatbuf;    if (vpw->pw_gid & BOUNCE_MAIL ) {        printf("vdelivermail: account is locked email bounced %s@%s\n",            TheUser, TheDomain);        vexit(100);    }    /* If thier directory path is empty make them a new one */    if ( vpw->pw_dir == NULL || vpw->pw_dir[0]==0 ) {        if ( make_user_dir(vpw->pw_name, TheDomain,                TheDomainUid, TheDomainGid)==NULL){            printf("Auto creation of maildir failed. vpopmail (#5.9.8)\n");            vexit(100);        }        /* Re-read the vpw entry, because we need to lookup the newly created         * pw_dir entry         */        if ((vpw=vauth_getpw(TheUser, TheDomain)) == NULL ) {           printf("Failed to vauth_getpw(). vpopmail (#5.9.8.1)\n");           vexit(100);        }    }    /* check if the directory exists and create if needed */    if ( stat(vpw->pw_dir, &mystatbuf ) == -1 ) {        if ( vmake_maildir(TheDomain, vpw->pw_dir )!= VA_SUCCESS ) {            printf("Auto re-creation of maildir failed. vpopmail (#5.9.9)\n");            vexit(100);        }    }    /* check for a .qmail file in thier Maildir     * If it exists, then deliver to the contents and exit     */    if ( check_forward_deliver(vpw->pw_dir) == 1 ) {        vexit(0);    }    snprintf(TheDir, AUTH_SIZE, "%s/Maildir/", vpw->pw_dir);    if ( deliver_mail(TheDir, vpw->pw_shell) != 0 ) {        vexit(100);    }}/* * the vpopmail user does not exist. Follow the rest of * the directions in the .qmail-default file */void usernotfound() { int ret;    /* If they want to delete email for non existant users     * then just exit 0. Qmail will delete the email for us     */    if ( strcmp(bounce, DELETE_ALL) == 0 ) {        /* just exit 0 and qmail will delete the email from the system */        vexit(0);    /* If they want to bounce the email back then     * print a message and exit 100     */    } else if ( strcmp(bounce, BOUNCE_ALL) == 0 ) {      FILE *fs;      char *tmp_file;        tmp_file = malloc(256);        sprintf(tmp_file, "%s/.no-user.msg",TheDomainDir);        if ( (fs=fopen(tmp_file, "r")) == NULL ) {            /* if no domain no user then check in vpopmail dir */            sprintf(tmp_file, "%s/domains/.no-user.msg",VPOPMAILDIR);            fs=fopen(tmp_file, "r");        }        if ( fs == NULL ) { 	    printf("Sorry, no mailbox here by that name. vpopmail (#5.1.1)\n");        } else {            while( fgets( tmp_file, 256, fs ) != NULL ) {               fputs(tmp_file, stdout);            }            fclose(fs);        }        free(tmp_file);        /* exit 100 causes the email to be bounced back */        vexit(100);    }    /* check if it is a path add the /Maildir/ for delivery */    if ( bounce[0] == '/' ) {        if (bounce[strlen(bounce)-1] != '/') strcat( bounce, "/");        printf ("user does not exist, but will deliver to %s\n", bounce);        if( check_forward_deliver(bounce) == 1 )            vexit(0);        else            strcat( bounce, "Maildir/");    }    ret = deliver_mail(bounce, "NOQUOTA" );    /* Send the email out, if we get a -1 then the user is over quota */    if ( ret == -1 ) {        printf("user is over quota, mail bounced\n");        vexit(100);    } else if ( ret == -2 ) {        printf("system error\n");        vexit(100);    } else if ( ret != 0 ) {        printf("mail is looping\n");        vexit(100);    }}/*  * Deliver an quota warning message * Return 0 on success * Return less than zero on failure *  * -1 = user is over quota * -2 and below are system failures * -3 mail is looping  */int deliver_quota_warning(const char *dir, const char *q){ time_t tm; long unsigned pid; long unsigned wrn_msg_sz; int write_fd, fdin, fd; size_t l; char newdir[400]; char *qname = 0; struct stat     sb; char    buf[4096]; FILE *fs; char quotawarnmsg[BUFF_SIZE];    /* Look in the domain for a .quotawarn.msg */    sprintf(quotawarnmsg, "%s/.quotawarn.msg", TheDomainDir);    if ( ((fdin=open(quotawarnmsg, O_RDONLY)) < 0) ||            (stat(quotawarnmsg, &sb)<0)) {        /* if that fails look in vpopmail dir */        sprintf(quotawarnmsg, "%s/domains/.quotawarn.msg", VPOPMAILDIR);        if ( ((fdin=open(quotawarnmsg, O_RDONLY)) < 0) ||               (stat(quotawarnmsg, &sb)<0)) {            return(0);        }    }    wrn_msg_sz = sb.st_size;    l = strlen(dir)+sizeof("/quotawarn");    if ((qname = malloc(l)) == 0)    {            close(fdin);            perror("malloc");            return(-1);    }    strcat(strcpy(qname, dir), "/quotawarn");    time(&tm);    /* Send only one warning every 24 hours */    if (stat(qname, &sb) == 0 && ((sb.st_mtime + 86400) > tm))    {            free(qname);            close(fdin);            return(0);    }    fd = open(qname, O_WRONLY|O_CREAT|O_TRUNC, 0644);    if (!fd)    {            free(qname);            close(fdin);            perror("open");            exit(111);    }    write(fd, buf, 0);    close(fd);    /* Format the email file name */    gethostname(hostname,sizeof(hostname));    pid=getpid();    time (&tm);    snprintf(local_file, 156, "%stmp/%lu.%lu.%s,S=%lu",        dir,(long unsigned)tm,pid,hostname, wrn_msg_sz);    snprintf(local_file_new, 156, "%snew/%lu.%lu.%s,S=%lu",        dir,(long unsigned)tm,pid,hostname,wrn_msg_sz);    /* open the new email file */    if ((write_fd=open(local_file,O_CREAT|O_RDWR,S_IRUSR|S_IWUSR))== -1) {        printf("can not open new email file errno=%d file=%s\n",             errno, local_file);        return(-2);    }    if ( strcmp( dir, bounce) == 0 ) {        snprintf(DeliveredTo, sizeof(DeliveredTo),             "%s%s%s", getenv("RPLINE"), getenv("DTLINE"), date_header());    } else {        strcpy(newdir, dir);        snprintf(DeliveredTo, sizeof(DeliveredTo),             "%sDelivered-To: %s\n%s", getenv("RPLINE"),             maildir_to_email(newdir), date_header());    }    /* write the Return-Path: and Delivered-To: headers */    if (write(write_fd,DeliveredTo,strlen(DeliveredTo)) != strlen(DeliveredTo)) {        close(write_fd);        /* Check if the user is over quota */        if ( errno == EDQUOT ) {            return(-1);        } else {            printf("failed to write delivered to line errno=%d\n",errno);            return(errno);        }    }    /* read the quota message in chunks and write it to the new file */    if((fs=fopen(quotawarnmsg, "ro")) != NULL) {        while(fgets(buf, MSG_BUF_SIZE, fs)) {            if ( write(write_fd,buf,strlen(buf)) == -1 ) {                close(write_fd);                /* if the write fails and we are writing to a Maildir                * then unlink the file                */                if ( unlink(local_file) != 0 ) {                    printf("unlink failed %s errno = %d\n", local_file, errno);                    return(errno);                }                /* Check if the user is over quota */                if ( errno == EDQUOT ) {                    return(-1);                } else {                    printf("write failed errno = %d\n", errno);                    return(errno);                }            }        }    }    /* since we are writing to a Maildir, move it    * into the new directory    */    /* sync the data to disk and close the file */    errno = 0;    if ( #ifdef FILE_SYNC#ifdef HAVE_FDATASYNC        fdatasync(write_fd) == 0 &&#else        fsync(write_fd) == 0 &&#endif#endif        close(write_fd) == 0 ) {        /* if this succeeds link the file to the new directory */        if ( link( local_file, local_file_new ) == 0 ) {            if ( unlink(local_file) != 0 ) {                printf("unlink failed %s errno = %d\n", local_file, errno);            }        } else {            /* coda fs has problems with link, check for that error */            if ( errno==EXDEV ) {                /* try to rename the file instead */                if (rename(local_file, local_file_new)!=0) {                    /* even rename failed, time to give up */                    printf("rename failed %s %s errno = %d\n",                         local_file, local_file_new, errno);                    return(errno);                /* rename worked, so we are okay now */                } else {                    errno = 0;                }            /* link failed and we are not on coda */            } else {                printf("link fucking failed %s %s errno = %d\n",                     local_file, local_file_new, errno);            }        }    }    /* return success */    add_warningsize_to_quota(dir,q);    return(0);}int is_loop_match( char *dt, char *address){ char *startdt;    startdt = dt;    /* walk forward in dt line for @ character */    while ( *dt != '@' && *dt != 0 ) ++dt;    if (*dt == 0) return 0;  /* no @ character found */    /* now walk back to first space */    while ( *dt != ' ' && dt != startdt) --dt;    /* step forward one character */    ++dt;   /* strcmp up to end of line or newline */   while ( *dt != 0 && *dt != '\n' && *dt != '\r' ) {     /* if it does not match, then no loop */     if ( *dt != *address ) return(0);     ++dt;     ++address;   }   /* we have a match */   return(1);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -