/* * ImapProxy - a caching IMAP proxy daemon * Copyright (C) 2002 Steven Van Acker * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * */ #include #include #include #include #include #include #include #include #include #include #include #include #include int option_version = 0; char *option_config_file = DEFAULT_CONFIG_FILE; int option_print_config=0; int option_help = 0; int rehash_flag = 0; /* function called when a child terminates */ void sigchldhandler(int x) { int r; debug("SIGCHLD generated !\n"); while((r = waitpid(-1,NULL,WNOHANG)) > 0); if(r < 0) { debug("sigchldhandler(): waitpid returned error (%s)\n",strerror(errno)); } /* some old unices seem to remove the signal handler after it was called. * so we replace it. */ signal(SIGCHLD,sigchldhandler); } /* function to call on SIGHUP */ void sighup(int x) { debug("sighup(): Got SIGHUP signal.\n"); rehash_flag = 1; } /* * This function checks whether the given word is * in the form {123} * * returns 1 on success * 0 on failure */ int word_is_literal_start(char *buf) { char *p,*q,*i; p = buf; /* check if next letter is '{' */ if(*p != '{') return 0; /* check if the string ends with "}\r\n" */ q = buf + strlen(buf) - 1; if(*q-- != '}') return 0; p++; i = p; while(i <= q) { if(!isdigit(*i)) return 0; i++; } return 1; } /* * This function checks whether the given string ends with the start of a literal * and returns the length of the literal on success, or -1 if none found. * * The string should not be crlf stripped */ int check_for_literal_count(char *buf) { char *p,*q,*i; if(!(p = strrchr(buf,'{'))) return -1; /* check if the string ends with "}\r\n" */ q = buf + strlen(buf) - 1; if(*q-- != '\n') return -1; if(*q-- != '\r') return -1; if(*q-- != '}') return -1; p++; i = p; while(i <= q) { if(!isdigit(*i)) return -1; i++; } return (int)strtol(p,NULL,10); } /* parse the options given to the program, and handle them */ int parse_options(int argc,char **argv) { int c = 0; while((c = getopt(argc,argv,"hvcf:")) != EOF) { switch((char)c) { case 'v': option_version = 1; break; case 'f': option_config_file = optarg; break; case 'c': option_print_config = 1; break; case 'h': case ':': case '?': default: option_help = 1; break; } } return optind; } int version() { fprintf(stderr,PROGNAME " " VERSION " by " AUTHOR ".\n\n"); return 0; } int usage(char *prog) { fprintf( stderr, "Usage:\n" "\t%s\t-v -h -c -f \n\n" "\t-v\tPrint version information and exit.\n" "\t-h\tPrint this help screen and exit.\n" "\t-c\tPrint parsed configfile and exit.\n" "\t-f file\tRead \"file\" as the config file.\n\n",prog); return 0; } int my_daemon() { int i = 0,n = 0; if((n = fork()) < 0) { debug("my_daemon(): Could not fork !! (%m)\n"); return -1; } if(n) { /* exit parent */ exit(0); } /* create a new session to get rid of the controlling tty */ if (setsid() < 0) { debug("my_daemon(): Can't setsid() !\n"); return -1; } if((n = fork())<0) { debug("my_daemon(): Could not fork !! (%m)\n"); return -1; } if(n) { exit(0); } n = sysconf(_SC_OPEN_MAX); for(i = 0;i < n;i++) close(i); /* open fd 0 to /dev/null */ open("/dev/null",O_RDWR); /* fd 1 */ dup(0); /* fd 2 */ dup(0); return 0; } char *my_strndup(char *s,int n) { char *out = NULL; if(!(out = malloc(n+1))) { debug("my_strndup(): Out of memory\n"); return NULL; } strncpy(out,s,n); out[n] = '\0'; return out; }