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

📄 vqmaillocal.c

📁 相当优秀的 UNIX 进程管理工具
💻 C
📖 第 1 页 / 共 2 页
字号:
         */	if ( (dtline = getenv("DTLINE")) != NULL ) {		while (*dtline!=0 && *dtline!=':' ) ++dtline;		while (*dtline!=0 && *dtline!='-' ) ++dtline;		if ( *dtline != 0 ) ++dtline;                for(tstr=dtline;*tstr!=0;++tstr) if (*tstr=='\n') *tstr=0;	} else {	        if (*address=='&') ++address;		dtline = address;	}        snprintf(DeliveredTo, AUTH_SIZE,             "%sDelivered-To: %s\n", getenv("RPLINE"), dtline);    }    if ( lseek(0, 0L, SEEK_SET) < 0 ) {        printf("lseek errno=%d\n", errno);        return(errno);    }    /* 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 it in chunks and write it to the new file */    while((file_count=read(0,msgbuf,MSG_BUF_SIZE))>0) {        if ( write(write_fd,msgbuf,file_count) == -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);            }        }    }    if ( inject == 1 ) {	close(write_fd);	return(0);    }    /* if 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 failed %s %s errno = %d\n",                     local_file, local_file_new, errno);            }        }    }    /* return success */    return(0);}/* Check if the vpopmail user has a .qmail file in thier directory * and foward to each email address, Maildir or program  *  that is found there in that file * * Return: 1 if we found and delivered email *       : 0 if not found *       : -1 if no user .qmail file  * */int check_forward_deliver(char *dir){ static char qmail_line[500]; char tmpbuf[500]; FILE *fs; int i; int return_value = 0;    /* format the file name */    snprintf(tmpbuf, 500, "%s/.qmail", dir);    if ( (fs = fopen(tmpbuf,"r")) == NULL ) {        /* no file, so just return */        return(-1);    }    /* format a simple loop checker name */    snprintf(tmpbuf, 500, "%s@%s", TheUser, TheDomain);    /* read the file, line by line */    while ( fgets(qmail_line, 500, fs ) != NULL ) {        /* remove the trailing new line */        for(i=0;qmail_line[i]!=0;++i) {            if (qmail_line[i] == '\n') qmail_line[i] = 0;        }        /* simple loop check, if they are sending it to themselves         * then skip this line         */        if ( strcmp( qmail_line, tmpbuf) == 0 ) continue;        deliver_mail(qmail_line, "NOQUOTA");        return_value = 1;    }    /* close the file */    fclose(fs);    /* return if we found one or not */    return(return_value);}void sig_catch(sig,f)int sig;void (*f)();{#ifdef HAVE_SIGACTION  struct sigaction sa;  sa.sa_handler = f;  sa.sa_flags = 0;  sigemptyset(&sa.sa_mask);  sigaction(sig,&sa,(struct sigaction *) 0);#else  signal(sig,f); /* won't work under System V, even nowadays---dorks */#endif}/* open a pipe to a command  * return the pid or -1 if error */void run_command(char *prog){ int child; char *(args[4]); int wstat; while (*prog==' ') ++prog; while (*prog=='|') ++prog;    if ( lseek(0, 0L, SEEK_SET) < 0 ) {        printf("lseek errno=%d\n", errno);        return;    } switch(child = fork())  {   case -1:     printf("unable to fork\n");      exit(0);   case 0:     args[0] = "/bin/sh"; args[1] = "-c"; args[2] = prog; args[3] = 0;     sig_catch(SIGPIPE,SIG_DFL);     execv(*args,args);     printf("Unable to run /bin/sh: ");     exit(-1);  }  wait(&wstat);}/* Check for a looping message * This is done by checking for a matching line * in the email headers for Delivered-To: which * we put in each email *  * Return 1 if looping * Return 0 if not looping * Return -1 on error  */int is_looping( char *address ) { int i; int found; char *dtline;    /* if we don't know the message size then get it */    if ( message_size == 0 ) {        /* read the message to get the size */        message_size = get_message_size();    }    if (*address=='&') ++address;    /* check the DTLINE */    dtline = getenv("DTLINE");    if ( dtline != NULL && strstr(dtline, address) != NULL ) {	return(1);    }    lseek(0,0L,SEEK_SET);    while(fgets(loop_buf,sizeof(loop_buf),stdin)!=NULL){        /* if we find the line, return error (looping) */        if (strstr(loop_buf, "Delivered-To")!= 0 &&             strstr(loop_buf, address)!=0 ) {            /* 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;    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 if the user is over quota * * Do all quota recalculation needed * * Return 1 if user is over quota * Return 0 if user is not over quota */int user_over_quota(char *maildir, char *quota){ ssize_t per_user_limit; off_t cur_msg_bytes; int i; int ret_value = 0; off_t new_size;    /* translate the quota to a number */    per_user_limit = atol(quota);    for(i=0;quota[i]!=0;++i){        if ( quota[i] == 'k' ||             quota[i] == 'K' ) {            per_user_limit = per_user_limit * 1000;            break;        }        if ( quota[i] == 'm' || quota[i] == 'M' ) {            per_user_limit = per_user_limit * 1000000;            break;        }    }    /* Get thier current total */    cur_msg_bytes = check_quota(maildir);    /* Check if this email would bring them over quota */    if ( cur_msg_bytes + message_size > per_user_limit ) {        /* recalculate thier quota since they might have         * deleted email          */        cur_msg_bytes = recalc_quota(maildir);        if ( cur_msg_bytes + message_size > per_user_limit ) {            ret_value = 1;        }    }    /* If we are going to deliver it, then add in the size */    if ( ret_value == 0 ) {        new_size = message_size + cur_msg_bytes;        update_quota(new_size);    }     close(CurrentQuotaSizeFd);    return(ret_value);}/* * check for locked account * deliver to .qmail file if any * deliver to user if no .qmail file */void checkuser() {    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 ) {      uid_t pw_uid;      gid_t pw_gid;	vget_assign(TheDomain,NULL,0,&pw_uid,&pw_gid);        if ( make_user_dir(vpw->pw_name, TheDomain, pw_uid, pw_gid)==NULL){            printf("Auto creation of maildir failed. vpopmail (#5.9.8)\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 ) {        printf("Sorry, no mailbox here by that name. vpopmail (#5.1.1)\n");        /* exit 100 causes the email to be bounced back */        vexit(100);    }    /* check if it is a path add the /Maildir/ for delivery */    if ( strstr( bounce, VPOPMAILDIR ) != 0 ) {        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);    }}

⌨️ 快捷键说明

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