/* * misc.c, SJ */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "misc.h" #include "smtpcodes.h" #include "errmsg.h" #include "config.h" #include "tai.h" /* * fatal function for quitting */ void __fatal(char *s){ fprintf(stderr, "%s\n", s); exit(1); } /* * calculate the difference betwwen two timevals in [usec] */ long tvdiff(struct timeval a, struct timeval b){ double res; res = (a.tv_sec * 1000000 + a.tv_usec) - (b.tv_sec * 1000000 + b.tv_usec); return (long) res; } /* * search something in a buffer */ int searchStringInBuffer(char *s, int len1, char *what, int len2){ int i, k, r; for(i=0; i 0){ p[k] = to; k++; } } else { p[k] = p[i]; k++; } } p[k] = '\0'; } /* * split a string by a character as delimiter */ char *split(char *row, int ch, char *s, int size){ char *r; int len; if(row == NULL) return NULL; r = strchr(row, ch); if(r == NULL){ len = strlen(row); if(len > size) len = size; } else { len = strlen(row) - strlen(r); if(len > size) len = size; r++; } if(s != NULL){ strncpy(s, row, len); s[len] = '\0'; } return r; } /* * split a string by a string as delimiter */ char *split_str(char *row, char *what, char *s, int size){ char *r; int len; memset(s, 0, size); if(row == NULL) return NULL; r = strstr(row, what); if(r == NULL){ len = strlen(row); if(len > size) len = size; } else { len = strlen(row) - strlen(r); if(len > size) len = size; r += strlen(what); } if(s != NULL){ strncpy(s, row, len); s[len] = '\0'; } return r; } /* * trim trailing CR-LF */ void trimBuffer(char *s){ char *p; p = strrchr(s, '\n'); if(p) *p = '\0'; p = strrchr(s, '\r'); if(p) *p = '\0'; } int extractEmail(char *rawmail, char *email){ char *p; p = strchr(rawmail, '<'); if(p){ snprintf(email, SMALLBUFSIZE-1, "%s", p+1); p = strchr(email, '>'); if(p){ *p = '\0'; return 1; } } return 0; } void create_id(char *id){ int i; unsigned char buf[RND_STR_LEN/2]; memset(id, 0, SMALLBUFSIZE); get_random_bytes(buf, RND_STR_LEN/2); for(i=0; i < RND_STR_LEN/2; i++){ sprintf(id, "%02x", buf[i]); id += 2; } } /* * reading from pool */ int get_random_bytes(unsigned char *buf, int len){ int fd, ret=0; struct taia now; char nowpack[TAIA_PACK]; /* the first 12 bytes are the taia timestamp */ taia_now(&now); taia_pack(nowpack, &now); memcpy(buf, nowpack, 12); fd = open(RANDOM_POOL, O_RDONLY); if(fd == -1) return ret; if(readFromEntropyPool(fd, buf+12, len-12) != len-12){ syslog(LOG_PRIORITY, "%s: %s", ERR_CANNOT_READ_FROM_POOL, RANDOM_POOL); } close(fd); return ret; } /* * read random data from entropy pool */ int readFromEntropyPool(int fd, void *_s, size_t n){ char *s = _s; ssize_t res, pos = 0; while(n > pos){ res = read(fd, s + pos, n - pos); switch(res){ case -1: continue; case 0: return res; default : pos += res; } } return pos; } /* * recv() with timeout */ int recvtimeout(int s, char *buf, int len, int timeout){ fd_set fds; int n; struct timeval tv; memset(buf, 0, MAXBUFSIZE); FD_ZERO(&fds); FD_SET(s, &fds); tv.tv_sec = timeout; tv.tv_usec = TIMEOUT_USEC; n = select(s+1, &fds, NULL, NULL, &tv); if (n == 0) return -2; // timeout! if (n == -1) return -1; // error return recv(s, buf, len, 0); } /* * is it a valid dotted IPv4 address */ int isDottedIPv4Address(char *s){ struct in_addr addr; if(inet_aton(s, &addr) == 0) return 0; return 1; } void write_pid_file(char *pidfile){ FILE *f; f = fopen(pidfile, "w"); if(f){ fprintf(f, "%d", (int)getpid()); fclose(f); } else syslog(LOG_PRIORITY, "cannot write pidfile: %s", pidfile); } int drop_privileges(struct passwd *pwd){ if(pwd->pw_uid > 0 && pwd->pw_gid > 0){ if(getgid() != pwd->pw_gid){ if(setgid(pwd->pw_gid)) return -1; } if(getuid() != pwd->pw_uid){ if(setuid(pwd->pw_uid)) return -1; } } return 0; } #ifndef _GNU_SOURCE char *strcasestr(const char *s, const char *find){ char c, sc; size_t len; if((c = *find++) != 0){ c = tolower((unsigned char)c); len = strlen(find); do { do { if((sc = *s++) == 0) return (NULL); } while((char)tolower((unsigned char)sc) != c); } while (strncasecmp(s, find, len) != 0); s--; } return((char*)s); } #endif