void flag_incdir(void) { unsigned long pos; if (flag & FLAG_COMPILE) { pos = str_rchr(ctxt_incdir, '/'); if (pos) ctxt_incdir[str_rchr(ctxt_incdir, '/')] = 0; printf("-I%s ", ctxt_incdir); } else { printf("%s ", ctxt_incdir); } }
unsigned int fileassociation_geticonid(const string ext) { letter apext[255]; letter apcls[255]; letter rvalue[260]; unsigned long rvsize = sizeof(rvalue); const string cls_name = uni("fennec.player.file."); int iconid = 0; string pt; apext[0] = uni('.'); str_cpy(apext + 1, ext); str_cpy(apcls, cls_name); str_cat(apcls, ext); /* i.e. "fennec.player.file.ogg" */ str_cat(apcls, uni("\\DefaultIcon")); if(RegQueryValue(HKEY_CLASSES_ROOT, apcls, rvalue, (PLONG)&rvsize) != ERROR_SUCCESS) goto pt_retdefaultid; if(!rvsize) goto pt_retdefaultid; pt = str_rchr(rvalue, uni(',')); if(!pt) goto pt_retdefaultid; pt++; /* ',' */ while(*pt == uni(' '))pt++; iconid = str_stoi(pt); return iconid; pt_retdefaultid: /* default icon ids */ return get_default_file_icon(ext); }
static int decode_prvs(const char *s) { /* The BATV standard says the user part should have the format * "tag-type=tag-val=loc-core" where "loc-core" is the original local * address, but all the examples I could find in actual use had the * last two parts reversed. What a mess. So, I have to check if * either the first or second part is a valid prvs tag, and use the * other one. */ int at; int sep; if (s[at = str_rchr(s,'@')] == 0) return 0; /* Format: [email protected] */ for (sep = 5; sep < at && s[sep] != '='; ++sep) ; if (sep >= at) return 0; if (is_prvs_tag(s+5,sep-5)) { if (!stralloc_copys(&realsender,s+sep+1)) die_nomem(); if (!stralloc_0(&realsender)) die_nomem(); return 1; } /* Format: [email protected] */ for (sep = at - 1; sep > 5 && s[sep] != '='; --sep) ; if (is_prvs_tag(s + sep + 1, at - sep - 1)) { if (!stralloc_copyb(&realsender,s+5,sep-5)) die_nomem(); if (!stralloc_cats(&realsender,s+at)) die_nomem(); if (!stralloc_0(&realsender)) die_nomem(); return 1; } return 0; }
static int decode_srs(const char *s) { /* Format: [email protected] */ /* Format: [email protected] */ char sep; int at; int sep1; int sep2; if ((sep = *s++) == 0) return 0; if (s[at = str_rchr(s,'@')] == 0) return 0; for (sep2 = at - 1; sep2 > 1 && s[sep2] != '='; sep2--) ; /* s+sep2 = "=USER@..." */ for (sep1 = sep2 - 1; sep1 > 1 && s[sep1] != '='; sep1--) ; /* s+sep1 = "=DOMAIN=USER@..." */ if (sep2 <= 0) return 0; ++sep1; ++sep2; if (!stralloc_copyb(&realsender,s+sep2,at-sep2)) die_nomem(); if (!stralloc_append(&realsender,"@")) die_nomem(); if (!stralloc_catb(&realsender,s+sep1,sep2-sep1-1)) die_nomem(); if (!stralloc_0(&realsender)) die_nomem(); return 1; }
//void do_sender(const char *s) void do_sender(char *s) { char *x; int n; int a; int i; env_unset("QMAILNAME"); env_unset("MAILNAME"); env_unset("NAME"); env_unset("QMAILHOST"); env_unset("MAILHOST"); n = str_len(s); a = str_rchr(s, '@'); if (a == n) { env_put("QMAILUSER", s); return; } env_put("QMAILHOST",s + a + 1); x = (char *) alloc((a + 1) * sizeof(char)); if (!x) nomem(); for (i = 0; i < a; i++) x[i] = s[i]; x[i] = 0; env_put("QMAILUSER", x); alloc_free(x); }
/** Get the last component of a path. * * e.g. /data/a ---> a * * @param path Pointer to the path. * * @return Pointer to the last component or to the path itself. */ static char *get_last_path_component(char *path) { char *ptr; ptr = str_rchr(path, '/'); if (!ptr) return path; else return ptr + 1; }
int main(void) { const char *s = "ABCD1234EFGHXXXX"; const char *t = "ABCD1234EFGHXXXX"; const char *u = "AbCdEfGh"; const char *v = "aBcDeFgH"; char *x; long i; unsigned long pos; test_assert(str_chr(s, 'D') == 3); i = str_char(s, 'D', &pos); test_assert(i == 1); test_assert(pos == 3); test_assert(str_diff(s, t) == 0); test_assert(str_same(s, t)); test_assert(str_ndiff(s, t, 8) == 0); test_assert(str_nsame(s, t, 8) == 1); test_assert(str_casei_diff(u, v) == 0); test_assert(str_casei_same(u, v) == 1); test_assert(str_casei_ndiff(u, v, 8) == 0); test_assert(str_casei_nsame(u, v, 8) == 1);; test_assert(str_rchr(s, 'X') == 15); i = str_rchar(s, 'X', &pos); test_assert(i == 1); test_assert(pos == 15); test_assert(str_dup(s, &x)); test_assert(str_same(s, x) == 1); test_assert(str_nsame(s, x, 8) == 1); test_assert(str_starts(s, "ABCD") == 1); test_assert(str_starts(s, "XYZA") == 0); test_assert(str_starts(s, "1234EFGH1234EFGH1234EFGH") == 0); test_assert(str_ends(s, "XXXX") == 1); test_assert(str_ends(s, "ABCD") == 0); test_assert(str_ends(s, "GH1234EFGH123GH1234EFGH123") == 0); test_assert(str_len(s) == 16); str_toupper(x); test_assert(x[0] == 'A'); str_tolower(x); test_assert(x[0] == 'a'); return 0; }
int fat_directory_create_sfn(fat_directory_t *di, fat_dentry_t *de, const char *lname) { char name[FAT_NAME_LEN + 1]; char ext[FAT_EXT_LEN + 1]; char number[FAT_NAME_LEN + 1]; memset(name, FAT_PAD, FAT_NAME_LEN); memset(ext, FAT_PAD, FAT_EXT_LEN); memset(number, FAT_PAD, FAT_NAME_LEN); size_t name_len = str_size(lname); char *pdot = str_rchr(lname, '.'); ext[FAT_EXT_LEN] = '\0'; if (pdot) { pdot++; str_to_ascii(ext, pdot, FAT_EXT_LEN, FAT_SFN_CHAR); name_len = (pdot - lname - 1); } if (name_len > FAT_NAME_LEN) name_len = FAT_NAME_LEN; str_to_ascii(name, lname, name_len, FAT_SFN_CHAR); unsigned idx; for (idx = 1; idx <= FAT_MAX_SFN; idx++) { snprintf(number, sizeof(number), "%u", idx); /* Fill de->name with FAT_PAD */ memset(de->name, FAT_PAD, FAT_NAME_LEN + FAT_EXT_LEN); /* Copy ext */ memcpy(de->ext, ext, str_size(ext)); /* Copy name */ memcpy(de->name, name, str_size(name)); /* Copy number */ size_t offset; if (str_size(name)+str_size(number) + 1 > FAT_NAME_LEN) offset = FAT_NAME_LEN - str_size(number) - 1; else offset = str_size(name); de->name[offset] = '~'; offset++; memcpy(de->name + offset, number, str_size(number)); if (!fat_directory_is_sfn_exist(di, de)) return EOK; } return ERANGE; }
void make_verptarget(void) /* puts target with '=' instead of last '@' into stralloc verptarget */ /* and does set_cpverptarget */ { unsigned int i; i = str_rchr(target.s,'@'); stralloc_copyb(&verptarget,target.s,i); if (target.s[i]) { stralloc_append(&verptarget,'='); stralloc_cats(&verptarget,target.s + i + 1); } stralloc_0(&verptarget); set_cpverptarget(verptarget.s); }
char *str_path_dirname(const char *path) { /* empty string or '..' */ if (str_isempty(path) || str_equal(path, "..")) return str_dup("."); /* skip prefixing '/' but preserve exactly one */ while (*path && *(path+1) && *path == '/' && *(path+1) == '/') path++; int found = 0; char *p, *buf = str_dup(path); while ((p = str_rchr(buf, '/', str_len(buf)))) { /* remove trailing slash */ if (p[1] == 0 && p != buf) *p = 0; /* no basename was found until yet */ else if (!found) { *p = 0; found = 1; } /* a basename was found and no trailing slash anymore */ else break; } char *dn; /* path consists only of basename and slashes */ if (str_isempty(buf)) dn = str_dup("/"); /* path is relative or absolute, basename was stripped */ else if (p) dn = str_dup(buf); /* path is relative, no basename was stripped */ else dn = str_dup("."); free(buf); return dn; }
int open_for_writing(int64* fd,const char* name) { /* only allow creating files in world writable directories */ const char* c; char* x; struct stat ss; c=name+str_rchr(name,'/'); // if (!*c) return 0; /* no slashes? There's something fishy */ if (!*c) { x="."; } else { x=alloca(c-name+1); byte_copy(x,c-name,name); x[c-name]=0; } if (stat(x,&ss)==-1) return 0; /* better safe than sorry */ if (!(ss.st_mode&S_IWOTH)) return 0; return io_createfile(fd,name); }
/** Run the previously loaded program. * * @param rid * @param request * @return 0 on success, !0 on error. */ static void ldr_run(ipc_callid_t rid, ipc_call_t *request) { const char *cp; DPRINTF("Set task name\n"); /* Set the task name. */ cp = str_rchr(pathname, '/'); cp = (cp == NULL) ? pathname : (cp + 1); task_set_name(cp); /* Run program */ DPRINTF("Reply OK\n"); async_answer_0(rid, EOK); DPRINTF("Jump to entry point at %p\n", pcb.entry); entry_point_jmp(prog_info.entry, &pcb); /* Not reached */ }
char *shell_dirname(char *path) { unsigned long i; if(path == NULL) return dot; for(;;) { i = str_rchr(path, SLASH); if(path[i] == '\0') return dot; /* no slashes */ if(path[i + 1] == EOL && i) { /* remove trailing slashes */ while(path[i] == SLASH && i) path[i--] = EOL; continue; } if(i) while(path[i] == SLASH) path[i--] = EOL; /* slashes in the middle */ else path[1] = EOL; /* slash is first symbol */ return path; } }
char *str_path_basename(const char *path) { /* empty string */ if (str_isempty(path)) return str_dup("."); /* skip prefixing '/' */ while (*path && *path == '/') path++; /* string consisting entirely of '/' */ if (!*path) return str_dup("/"); char *p, *buf = str_dup(path); while ((p = str_rchr(buf, '/', str_len(buf)))) { /* remove trailing lash */ if (p[1] == 0 && p != buf) *p = 0; /* no trailing slash anymore */ else break; } char *bn; /* if a non-trailing slash was found, return everything after it */ if (p) bn = str_dup(p + 1); /* otherwise buf already contains basename */ else bn = str_dup(buf); free(buf); return bn; }
/* Returns a modified mail string if an alias_domain-real_domain mapping is found * It simply returns its argument if no mapping is found * On error returns NULL * */ char* replace_domain(const char* mail) { static stralloc new_mail = {0}; unsigned int at; char* new_domain; at = str_rchr(mail, '@'); if (mail[at] != '@') return (char*) 0; if (new_domain=qldap_domain_alias(mail + at + 1)) { if(!stralloc_copyb(&new_mail,mail,at + 1)) return (char*) 0; if(!stralloc_cats(&new_mail,new_domain)) return (char*) 0; if(!stralloc_0(&new_mail)) return (char*) 0; return new_mail.s; } return (char*) mail; /* Do nothing */ }
void main(int argc,char **argv) { char *dir; char *action; char *dtline; char *nhost; const char *err; unsigned int i; int match; int opt; sig_pipeignore(); while ((opt = getopt(argc,argv,"dDvV")) != opteof) { switch (opt) { case 'd': flagdo = 1; break; case 'D': flagdo = 0; break; case 'v': case 'V': strerr_die2x(0, "ezmlm-split version: ",auto_version); default: die_usage(); } } startup(dir = argv[optind++]); load_config(dir); if (!(split = argv[optind])) split = "split"; if (flagdo) { sender = env_get("SENDER"); if (!sender) strerr_die2x(100,FATAL,ERR_NOSENDER); if (!*sender) strerr_die2x(100,FATAL,ERR_BOUNCE); if (!sender[str_chr(sender,'@')]) strerr_die2x(100,FATAL,ERR_ANONYMOUS); if (str_equal(sender,"#@[]")) strerr_die2x(100,FATAL,ERR_BOUNCE); action = env_get("DEFAULT"); if (!action) strerr_die2x(100,FATAL,ERR_NODEFAULT); if (!stralloc_copys(&target,sender)) die_nomem(); if (action[0]) { i = str_chr(action,'-'); if (action[i]) { action[i] = '\0'; if (!stralloc_copys(&target,action + i + 1)) die_nomem(); i = byte_rchr(target.s,target.len,'='); if (i < target.len) target.s[i] = '@'; } } if (!stralloc_0(&target)) die_nomem(); if (case_diffs(action,ACTION_SUBSCRIBE) && case_diffs(action,ALT_SUBSCRIBE) && case_diffs(action,ACTION_UNSUBSCRIBE) && case_diffs(action,ALT_UNSUBSCRIBE)) _exit(0); /* not for us */ if (findname()) { /* new sender */ if (!stralloc_copy(&from,&outlocal)) die_nomem(); if (!stralloc_cats(&from,"-return-@")) die_nomem(); if (!stralloc_cat(&from,&outhost)) die_nomem(); if (!stralloc_0(&from)) die_nomem(); nhost = name.s + str_rchr(name.s,'@'); /* name must have '@'*/ *(nhost++) = '\0'; if (!stralloc_copys(&to,name.s)) die_nomem(); /* local */ if (!stralloc_append(&to,"-")) die_nomem(); /* - */ if (!stralloc_cats(&to,action)) die_nomem(); /* subscribe */ if (!stralloc_append(&to,"-")) die_nomem(); /* - */ if (target.s[i = str_rchr(target.s,'@')]) target.s[i] = '='; if (!stralloc_cats(&to,target.s)) die_nomem(); /* target */ if (!stralloc_append(&to,"@")) die_nomem(); /* - */ if (!stralloc_cats(&to,nhost)) die_nomem(); /* host */ if (!stralloc_0(&to)) die_nomem(); dtline = env_get("DTLINE"); if (!dtline) strerr_die2x(100,FATAL,ERR_NODTLINE); if (qmail_open(&qq,(stralloc *) 0) == -1) strerr_die2sys(111,FATAL,ERR_QMAIL_QUEUE); qmail_puts(&qq,dtline); /* delivered-to */ if (qmail_copy(&qq,subfdin,0) != 0) strerr_die2sys(111,FATAL,ERR_READ_INPUT); qmail_from(&qq,from.s); qmail_to(&qq,to.s); if (*(err = qmail_close(&qq)) != '\0') strerr_die3x(111,FATAL,ERR_TMP_QMAIL_QUEUE,err + 1); strnum[fmt_ulong(strnum,qmail_qp(&qq))] = 0; strerr_die3x(99,INFO,"qp ",strnum); } _exit(0); } else { for (;;) { if (getln(subfdin,&line,&match,'\n') == -1) strerr_die2sys(111,FATAL,ERR_READ_INPUT); if (!match) break; if (line.len == 1) continue; /* ignore blank lines */ if (line.s[0] == '#') continue; /* ignore comments */ if (!stralloc_copy(&target,&line)) die_nomem(); target.s[target.len - 1] = '\0'; (void) findname(); if (!stralloc_cats(&name,": ")) die_nomem(); if (!stralloc_cats(&name,target.s)) die_nomem(); if (!stralloc_append(&name,"\n")) die_nomem(); if (substdio_put(subfdout,name.s,name.len) == -1) strerr_die2sys(111,ERR_WRITE,"output: "); } if (substdio_flush(subfdout) == -1) strerr_die2sys(111,ERR_FLUSH,"output: "); _exit(0); } (void)argc; }
char * filter_mail(char *mail, int *done) { static char *escaped; static unsigned int at, ext, len = 0; #ifdef DASH_EXT unsigned int i; #endif if (mail == (char *)0) { len = 0; return 0; } if (len == 0) { #ifdef DOMAIN_ALIAS escaped = filter_escape(replace_domain(mail)); #else escaped = filter_escape(mail); #endif if (escaped == (char *)0) return 0; len = str_len(escaped); at = str_rchr(escaped, '@'); if (escaped[at] != '@') { len = 0; return 0; } ext = at; extcnt = -1; *done = 0; } else { if (extcnt == 0) { *done = 1; return 0; } #ifdef DASH_EXT /* * limit ext to the first DASH_EXT_LEVELS extensions. * We will only check for (DASH_EXT_LEVELS = 4): * [email protected] * [email protected] * [email protected] * [email protected] * [email protected] * [email protected] */ if (ext == at) for (i = 0, ext = 0, extcnt = 1; ext < at && extcnt <= DASH_EXT_LEVELS; ext++) if (escaped[ext] == *auto_break) extcnt++; while (ext != 0 && --ext > 0) { if (escaped[ext] == *auto_break) break; } extcnt--; #else /* basic qmail-ldap behavior test for [email protected] and [email protected] */ ext = 0; extcnt = 0; #endif } /* build the search string for the email address */ if (!stralloc_copys(&filter, "(|(" )) return 0; /* mail address */ if (!stralloc_cats(&filter, LDAP_MAIL)) return 0; if (!stralloc_cats(&filter, "=")) return 0; /* username till current '-' */ if (!stralloc_catb(&filter, escaped, ext)) return 0; if (ext != at) { /* do not append catchall in the first round */ /* catchall or default */ if (extcnt > 0) /* add '-' */ if (!stralloc_cats(&filter, auto_break)) return 0; if (!stralloc_cats(&filter, LDAP_CATCH_ALL)) return 0; } /* @damin.com */ if (!stralloc_catb(&filter, escaped+at, len-at)) return 0; /* mailalternate address */ if (!stralloc_cats(&filter, ")(")) return 0; if (!stralloc_cats(&filter, LDAP_MAILALTERNATE)) return 0; if (!stralloc_cats(&filter, "=")) return 0; /* username till current '-' */ if (!stralloc_catb(&filter, escaped, ext)) return 0; if (ext != at) { /* do not append catchall in the first round */ /* catchall or default */ if (extcnt > 0) /* add '-' */ if (!stralloc_cats(&filter, auto_break)) return 0; if (!stralloc_cats(&filter, LDAP_CATCH_ALL)) return 0; } /* @domain.com */ if (!stralloc_catb(&filter, escaped+at, len-at)) return 0; if (!stralloc_cats(&filter, "))")) return 0; if (!stralloc_0(&filter)) return 0; if (extcnt == 0) *done = 1; return filter_objectclass(filter.s); }
const char* mimetype(const char* filename,int fd) { int i,e=str_rchr(filename,'.'); if (filename[e]) { ++e; if (mimetypesfilename) { const char* x=find_mime_type(filename+e,mimetypesfilename,now.sec.x-4611686018427387914ULL); if (x) return x; } for (i=0; mimetab[i].name; ++i) if (str_equal(mimetab[i].name,filename+e)) return mimetab[i].type; } #ifdef SUPPORT_MIMEMAGIC { char buf[300]; int r; r=pread(fd,buf,sizeof(buf),0); if (r>=1 && buf[0]=='<') { if (r>1 && buf[1]=='?') { char* c; if (r>=100) for (c=buf+1; c<buf+r-5; ++c) { if (*c=='<') { if (c<buf+r-8 && byte_equal(c,8,"<rdf:RDF")) return "application/rss+xml"; else if (c<buf+r-8 && byte_equal(c,5,"<rss ")) return "application/rss+xml"; } } return "text/xml"; } else if (buf[1]=='!' || isalnum(buf[1])) return "text/html"; } else if (r>=5 && byte_equal(buf,4,"GIF9")) return "image/gif"; else if (r>=4 && byte_equal(buf,4,"\x89PNG")) return "image/png"; else if (r>=10 && byte_equal(buf,2,"\xff\xd8")) return "image/jpeg"; else if (r>=5 && byte_equal(buf,5,"%PDF-")) return "application/pdf"; else if (r>=4 && (byte_equal(buf,3,"ID3") || byte_equal(buf,2,"\xff\xfb"))) return "audio/mpeg"; else if (r>=200 && byte_equal(buf,4,"OggS")) { size_t i; for (i=0; i<200-6; ++i) if (buf[i]=='t' && byte_equal(buf+i+1,5,"heora")) return "video/ogg"; return "application/ogg"; } else if (r>=4 && byte_equal(buf,4,"RIFF")) { if (r>=16 && byte_equal(buf+8,3,"AVI")) return "video/x-msvideo"; else return "audio/x-wav"; } else if (r==100 && byte_equal(buf+4,4,"moov")) return "video/quicktime"; else if (r==100 && byte_equal(buf+4,8,"ftypqt ") && byte_equal(buf+0x24,4,"moov")) return "video/quicktime"; else if (r==100 && byte_equal(buf+4,7,"ftypmp4")) return "video/mp4"; else if (r>=4 && byte_equal(buf,4,"\x30\x26\xb2\x75")) return "video/x-ms-asf"; else if (r>=4 && (byte_equal(buf,4,"\177ELF") || byte_equal(buf,2,"#!"))) return magicelfvalue; } #else else return "text/plain";
int main(int argc, char* argv[]) { int index = 0, c; static const struct longopt opts[] = {{"help", 0, NULL, 'h'}, {"verbose", 0, 0, 'v'}, {0}}; errmsg_iam(argv[0]); for(;;) { c = getopt_long(argc, argv, "hv", opts, &index); if(c == -1) break; if(c == '\0') continue; switch(c) { case 'h': usage(argv[0]); return 0; case 'v': verbose = 1; break; default: { usage(argv[0]); return 1; } } } while(optind < argc) { const char* a = argv[optind++]; int i = str_rchr(a, '.'); if(str_equal(&a[i], ".list")) { buffer in; if(!buffer_mmapread(&in, a)) { stralloc target, link; ssize_t ret; stralloc_init(&target); stralloc_init(&link); for(;;) { if((ret = buffer_get_new_token_sa(&in, &target, " \t\v", 2)) < 0) break; if(ret == 0 || target.s[0] == '\0') break; if(target.len > 0) --target.len; if((ret = buffer_get_new_token_sa(&in, &link, "\r\n", 2)) < 0) break; if(ret == 0 || link.s[0] == '\0') break; stralloc_chomp(&link); mklink_sa(&target, &link); if(!stralloc_endb(&link, ".so", 3)) { if(sln(link.s)) return 1; } } buffer_close(&in); } } else { if(sln(argv[i])) return 1; } } }
int main (int argc, char* argv[]) { char ip[4]; stralloc partial = {0}; stralloc out = {0}; char ip_fmt[IP4_FMT]; char line[BUF_LEN]; int r, i, j; int inbuflen = 0; int flag0 = 1; buffer sslist; int fdlist = 0; char outlist[BUF_LEN]; unsigned long skip = 0; int opt; while ((opt = getopt (argc, argv, "s:")) != opteof) switch (opt) { case 's': scan_ulong (optarg, &skip); break; default: usage (); } argc -= optind; argv += optind; if (!argc) usage (); fdlist = open_append(argv[0]); if (fdlist == -1) strerr_die4sys (111,FATAL,"unable to write ",argv[0],": "); buffer_init (&sslist,write,fdlist,outlist,sizeof(outlist)); if (!stralloc_copys (&partial, "")) nomem (); while (flag0 || inbuflen || partial.len) { if (flag0) if (inbuflen < sizeof line) { r = read (0, line+inbuflen, sizeof line-inbuflen); if (r <= 0) flag0 = 0; else inbuflen += r; } while (flag0) { i = byte_chr (line, inbuflen, '\n'); if (inbuflen && (i == inbuflen)) { if (!stralloc_catb (&partial, line, inbuflen)) nomem (); inbuflen = 0; continue; } if ((i < inbuflen) || (!flag0 && partial.len)) { if (i < inbuflen) ++i; if (!stralloc_catb (&partial, line, i)) nomem (); inbuflen -= i; for (j = 0; j < inbuflen; ++j) line[j] = line[j + i]; /* end of header */ if (partial.len == 1) { inbuflen = partial.len = flag0 = 0; break; } if (partial.len && flag0) { if (str_start (partial.s, "Received: from ")) { for (j = str_rchr (partial.s, '(')+1; flag0 && j; j--) { i = ip4_scan (partial.s+j, ip); if (skip && i) { skip--; break; } if (i) { /* write the IP to the output file */ stralloc_copyb (&out,ip_fmt, ip4_fmt (ip_fmt, ip)); buffer_put (&sslist, out.s, out.len); buffer_puts (&sslist, "\n"); flag0 = 0; inbuflen = 0; } } } } partial.len = 0; continue; } break; } } /* flush and close output file */ buffer_flush (&sslist); fsync(fdlist); close(fdlist); _exit (EXIT_OK); }
char * filter_mail(char *mail, int *done) { char *domain, *alias; unsigned int at; int round; #ifdef DASH_EXT unsigned int i; #endif if (mail == (char *)0) { ext = 0; return 0; } at = str_rchr(mail, '@'); if (at == 0 || mail[at] != '@') { ext = 0; return 0; } domain = mail + at + 1; if (adok) { alias = constmap(&ad_map, domain, str_len(domain)); if (alias && *alias) domain = alias; } if (ext == 0) { ext = at; extcnt = -1; *done = 0; } else { if (extcnt == 0) { *done = 1; ext = 0; return 0; } #ifdef DASH_EXT /* * limit ext to the first DASH_EXT_LEVELS extensions. * We will only check for (DASH_EXT_LEVELS = 4): * [email protected] * [email protected] * [email protected] * [email protected] * [email protected] * [email protected] */ if (ext == at) for (i = 0, ext = 0, extcnt = 1; ext < at && extcnt <= DASH_EXT_LEVELS; ext++) if (mail[ext] == *auto_break) extcnt++; while (ext != 0 && --ext > 0) { if (mail[ext] == *auto_break) break; } extcnt--; #else #error XXX XXX /* basic qmail-ldap behavior test for [email protected] and [email protected] */ ext = 0; extcnt = 0; #endif } for (round = 0; round < 2; round++) { switch (round) { case 0: /* build the search string for the email address */ /* mail address */ if (!filter_start(&filter) || !stralloc_cats(&filter, "(|(") || !stralloc_cats(&filter, LDAP_MAIL) || !stralloc_cats(&filter, "=")) return 0; break; case 1: /* mailalternate address */ if (!stralloc_cats(&filter, ")(") || !stralloc_cats(&filter, LDAP_MAILALTERNATE) || !stralloc_cats(&filter, "=")) return 0; break; } /* username till current '-' or '@' */ if (!filter_escape(&filter, mail, ext)) return 0; /* do not append catchall in the first round */ if (ext != at) { /* catchall or default */ if (extcnt > 0) /* add '-' */ if (!stralloc_cats(&filter, auto_break)) return 0; if (!stralloc_cats(&filter, LDAP_CATCH_ALL)) return 0; } /* @domain.com */ if (!stralloc_append(&filter, "@") || !filter_escape(&filter, domain, str_len(domain))) return 0; } if (!stralloc_cats(&filter, "))") || !filter_end(&filter)) return 0; if (extcnt == 0) *done = 1; if (mail[0] == *auto_break) *done = 1; // OSC: do not do DASH_EXT loop if first char is auto_break return filter.s; }
void main(int argc,char **argv) { char *dir; int fdlock; char *sender; int match; int flaginheader; int flagmodpost; int flagremote; const char *pmod; const char *err; int opt; unsigned int i; char szchar[2] = "-"; int child; (void) umask(022); sig_pipeignore(); if (!stralloc_copys(&sendopt,"-")) die_nomem(); while ((opt = getopt(argc,argv,"bBcCmMpPrRsSvVyY")) != opteof) switch(opt) { case 'b': flagbody = 1; break; case 'B': flagbody = 0; break; case 'm': flagmime = 1; break; case 'M': flagmime = 0; break; case 'p': flagpublic = 1; break; /* anyone can post (still moderated)*/ case 'P': flagpublic = 0; break; /* only moderators can post */ case 's': flagself = 1; break; /* modpost and DIR/mod diff fxns */ case 'S': flagself = 0; break; /* same fxn */ case 'y': flagconfirm = 1; break; /* force post confirmation */ case 'Y': flagconfirm = 0; break; /* disable post confirmation */ case 'c': /* ezmlm-send flags */ case 'C': case 'r': case 'R': szchar[0] = (char) opt & 0xff; if (!stralloc_append(&sendopt,szchar)) die_nomem(); break; case 'v': case 'V': strerr_die2x(0,"ezmlm-store version: ",auto_version); default: die_usage(); } sender = env_get("SENDER"); if (sender) { if (!*sender || str_equal(sender,"#@[]")) strerr_die2x(100,FATAL,ERR_BOUNCE); } startup(dir = argv[optind]); load_config(dir); if (flagconfirm == -1) flagconfirm = getconf_line(&confirmpost,"confirmpost",0,dir); else getconf_line(&confirmpost,"confirmpost",0,dir); flagmodpost = getconf_line(&moderators,"modpost",0,dir); flagremote = getconf_line(&line,"remote",0,dir); if (!flagmodpost && !flagconfirm) { /* not msg-mod. Pipe to ezmlm-send */ if ((child = wrap_fork()) == 0) wrap_execbin("/ezmlm-send", &sendopt, dir); /* parent */ wrap_exitcode(child); } if (!moderators.len || !(moderators.s[0] == '/')) { if (!stralloc_copys(&moderators,dir)) die_nomem(); if (!stralloc_cats(&moderators,"/mod")) die_nomem(); } if (!stralloc_0(&moderators)) die_nomem(); if (sender) { pmod = issub(moderators.s,0,sender); closesub(); /* sender = moderator? */ } else pmod = 0; if (!pmod && !flagpublic) strerr_die2x(100,FATAL,ERR_NO_POST); fdlock = lockfile("mod/lock"); if (!stralloc_copys(&mydtline, flagconfirm ? "Delivered-To: confirm to " : "Delivered-To: moderator for ")) die_nomem(); if (!stralloc_catb(&mydtline,outlocal.s,outlocal.len)) die_nomem(); if (!stralloc_append(&mydtline,"@")) die_nomem(); if (!stralloc_catb(&mydtline,outhost.s,outhost.len)) die_nomem(); if (!stralloc_cats(&mydtline,"\n")) die_nomem(); if (!stralloc_copys(&returnpath,"Return-Path: <")) die_nomem(); if (sender) { if (!stralloc_cats(&returnpath,sender)) die_nomem(); for (i = 14; i < returnpath.len;++i) if (returnpath.s[i] == '\n' || !returnpath.s[i] ) returnpath.s[i] = '_'; /* NUL and '\n' are bad, but we don't quote since this is */ /* only for ezmlm-moderate, NOT for SMTP */ } if (!stralloc_cats(&returnpath,">\n")) die_nomem(); pid = getpid(); /* unique file name */ for (i = 0;;++i) /* got lock - nobody else can add files */ { when = now(); /* when is also used later for date! */ if (!stralloc_copys(&fnmsg, flagconfirm?"mod/unconfirmed/":"mod/pending/")) die_nomem(); if (!stralloc_copyb(&fnbase,strnum,fmt_ulong(strnum,when))) die_nomem(); if (!stralloc_append(&fnbase,".")) die_nomem(); if (!stralloc_catb(&fnbase,strnum,fmt_ulong(strnum,pid))) die_nomem(); if (!stralloc_cat(&fnmsg,&fnbase)) die_nomem(); if (!stralloc_0(&fnmsg)) die_nomem(); if (stat(fnmsg.s,&st) == -1) if (errno == error_noent) break; /* really should never get to this point */ if (i == 2) strerr_die2x(111,FATAL,ERR_UNIQUE); sleep(2); } if (!stralloc_copys(&action,"-")) die_nomem(); if (!stralloc_cats(&action,flagconfirm?ACTION_DISCARD:ACTION_REJECT)) die_nomem(); if (!stralloc_cat(&action,&fnbase)) die_nomem(); if (!stralloc_0(&action)) die_nomem(); makeacthash(&action); if (!quote("ed,&outlocal)) die_nomem(); if (!stralloc_copy(&reject,"ed)) die_nomem(); if (!stralloc_cat(&reject,&action)) die_nomem(); if (!stralloc_0(&reject)) die_nomem(); if (!stralloc_copys(&action,"-")) die_nomem(); if (!stralloc_cats(&action,flagconfirm?ACTION_CONFIRM:ACTION_ACCEPT)) die_nomem(); if (!stralloc_cat(&action,&fnbase)) die_nomem(); if (!stralloc_0(&action)) die_nomem(); makeacthash(&action); if (!stralloc_copy(&accept,"ed)) die_nomem(); if (!stralloc_cat(&accept,&action)) die_nomem(); if (!stralloc_0(&accept)) die_nomem(); set_cptarget(accept.s); /* for copy () */ set_cpconfirm(reject.s,quoted.len); fdmsg = open_trunc(fnmsg.s); if (fdmsg == -1) strerr_die6sys(111,FATAL,ERR_WRITE,dir,"/",fnmsg.s,": "); substdio_fdbuf(&ssmsg,write,fdmsg,msgbuf,sizeof(msgbuf)); if (qmail_open(&qq, (stralloc *) 0) == -1) /* Open mailer */ strerr_die2sys(111,FATAL,ERR_QMAIL_QUEUE); hdr_add2("Mailing-List: ",mailinglist.s,mailinglist.len); if (listid.len > 0) hdr_add2("List-ID: ",listid.s,listid.len); hdr_datemsgid(when); if (flagconfirm) hdr_from("-owner"); else hdr_add2s("From: ",reject.s); hdr_add2s("Reply-To: ",accept.s); if (!flagconfirm && !pmod && flagremote) { /* if remote admin add -allow- address */ qmail_puts(&qq,"Cc: "); /* for ezmlm-gate users */ strnum[fmt_ulong(strnum,(unsigned long) when)] = 0; cookie(hash,key.s,key.len-FLD_ALLOW,strnum,sender,"t"); if (!stralloc_copy(&line,&outlocal)) die_nomem(); if (!stralloc_cats(&line,"-allow-tc.")) die_nomem(); if (!stralloc_cats(&line,strnum)) die_nomem(); if (!stralloc_append(&line,".")) die_nomem(); if (!stralloc_catb(&line,hash,COOKIE)) die_nomem(); if (!stralloc_append(&line,"-")) die_nomem(); i = str_rchr(sender,'@'); if (!stralloc_catb(&line,sender,i)) die_nomem(); if (sender[i]) { if (!stralloc_append(&line,"=")) die_nomem(); if (!stralloc_cats(&line,sender + i + 1)) die_nomem(); } qmail_put(&qq,line.s,line.len); qmail_puts(&qq,"@"); qmail_put(&qq,outhost.s,outhost.len); qmail_puts(&qq,"\n"); } qmail_puts(&qq,"To: <"); if (flagconfirm) { if (sender) qmail_puts(&qq, sender); } else { if (!quote("ed,&outlocal)) die_nomem(); qmail_put(&qq,quoted.s,quoted.len); qmail_puts(&qq,"-moderators@"); qmail_put(&qq,outhost.s,outhost.len); } qmail_puts(&qq,">\n"); /* FIXME: Drop the custom subject hack and use hdr_listsubject1 */ if (!stralloc_copys(&subject,"Subject: ")) die_nomem(); if (flagconfirm) { if (confirmpost.len) { if (!stralloc_cat(&subject,&confirmpost)) die_nomem(); if (!stralloc_cats(&subject," ")) die_nomem(); } else { if (!stralloc_cats(&subject,TXT_CONFIRM_POST)) die_nomem(); } } else { if (!stralloc_cats(&subject,TXT_MODERATE)) die_nomem(); } if (!quote("ed,&outlocal)) die_nomem(); if (!stralloc_cat(&subject,"ed)) die_nomem(); if (!stralloc_append(&subject,"@")) die_nomem(); if (!stralloc_cat(&subject,&outhost)) die_nomem(); if (flagmime) { hdr_mime(CTYPE_MULTIPART); qmail_put(&qq,subject.s,subject.len); hdr_boundary(0); hdr_ctype(CTYPE_TEXT); hdr_transferenc(); } else { qmail_put(&qq,subject.s,subject.len); qmail_puts(&qq,"\n\n"); } copy(&qq,flagconfirm?"text/post-confirm":"text/mod-request",flagcd); if (flagcd == 'B') { encodeB("",0,&line,2); qmail_put(&qq,line.s,line.len); } if (substdio_put(&ssmsg,returnpath.s,returnpath.len) == -1) die_msg(); if (substdio_put(&ssmsg,mydtline.s,mydtline.len) == -1) die_msg(); substdio_fdbuf(&ssin,read,0,inbuf,sizeof(inbuf)); if (flagmime) { hdr_boundary(0); hdr_ctype(CTYPE_MESSAGE); qmail_puts(&qq, "\n"); } qmail_put(&qq,returnpath.s,returnpath.len); qmail_put(&qq,mydtline.s,mydtline.len); flaginheader = 1; for (;;) { if (getln(&ssin,&line,&match,'\n') == -1) strerr_die2sys(111,FATAL,ERR_READ_INPUT); if (!match) break; if (line.len == 1) flaginheader = 0; if (flaginheader) { if ((line.len == mydtline.len) && !byte_diff(line.s,line.len,mydtline.s)) { close(fdmsg); /* be nice - clean up */ unlink(fnmsg.s); strerr_die2x(100,FATAL,ERR_LOOPING); } if (case_startb(line.s,line.len,"mailing-list:")) { close(fdmsg); /* be nice - clean up */ unlink(fnmsg.s); strerr_die2x(100,FATAL,ERR_MAILING_LIST); } } if (flagbody || flaginheader) /* skip body if !flagbody */ qmail_put(&qq,line.s,line.len); if (substdio_put(&ssmsg,line.s,line.len) == -1) die_msg(); } if (flagmime) hdr_boundary(1); /* close archive before qmail. Loss of qmail will result in re-run, and */ /* worst case this results in a duplicate msg sitting orphaned until it's */ /* cleaned out. */ if (substdio_flush(&ssmsg) == -1) die_msg(); if (fsync(fdmsg) == -1) die_msg(); if (fchmod(fdmsg,MODE_MOD_MSG | 0700) == -1) die_msg(); if (close(fdmsg) == -1) die_msg(); /* NFS stupidity */ close(fdlock); if (flagconfirm) { qmail_from(&qq,reject.s); /* envelope sender */ } else { if (!stralloc_copy(&line,&outlocal)) die_nomem(); if (!stralloc_cats(&line,"-return-@")) die_nomem(); if (!stralloc_cat(&line,&outhost)) die_nomem(); if (!stralloc_0(&line)) die_nomem(); qmail_from(&qq,line.s); /* envelope sender */ } if (flagconfirm) /* to sender */ qmail_to(&qq,sender); else if (pmod) /* to moderator only */ qmail_to(&qq,pmod); else { if (flagself) { /* to all moderators */ if (!stralloc_copys(&moderators,dir)) die_nomem(); if (!stralloc_cats(&moderators,"/mod")) die_nomem(); if (!stralloc_0(&moderators)) die_nomem(); } putsubs(moderators.s,0,0,52,subto,1); } if (*(err = qmail_close(&qq)) == '\0') { strnum[fmt_ulong(strnum,qmail_qp(&qq))] = 0; strerr_die2x(0,"ezmlm-store: info: qp ",strnum); } else strerr_die3x(111,FATAL,ERR_TMP_QMAIL_QUEUE,err+1); }
int main(int argc,char **argv) { char strnum[FMT_ULONG]; char *action; char *dtline; char *nhost; const char *err; unsigned int i; int match; int opt; sig_pipeignore(); opt = getconfopt(argc,argv,options,1,0); if (!(split = argv[opt])) split = "split"; if (flagdo) { sender = get_sender(); if (!sender) die_sender(); if (!*sender) strerr_die2x(100,FATAL,MSG(ERR_BOUNCE)); if (!sender[str_chr(sender,'@')]) strerr_die2x(100,FATAL,MSG(ERR_ANONYMOUS)); if (str_equal(sender,"#@[]")) strerr_die2x(100,FATAL,MSG(ERR_BOUNCE)); action = env_get("DEFAULT"); if (!action) strerr_die2x(100,FATAL,MSG(ERR_NODEFAULT)); if (!stralloc_copys(&target,sender)) die_nomem(); if (action[0]) { i = str_chr(action,'-'); if (action[i]) { action[i] = '\0'; if (!stralloc_copys(&target,action + i + 1)) die_nomem(); i = byte_rchr(target.s,target.len,'='); if (i < target.len) target.s[i] = '@'; } } if (!stralloc_0(&target)) die_nomem(); if (case_diffs(action,ACTION_SUBSCRIBE) && case_diffs(action,ALT_SUBSCRIBE) && case_diffs(action,ACTION_UNSUBSCRIBE) && case_diffs(action,ALT_UNSUBSCRIBE)) _exit(0); /* not for us */ if (findname()) { /* new sender */ if (!stralloc_copy(&from,&outlocal)) die_nomem(); if (!stralloc_cats(&from,"-return-@")) die_nomem(); if (!stralloc_cat(&from,&outhost)) die_nomem(); if (!stralloc_0(&from)) die_nomem(); nhost = name.s + str_rchr(name.s,'@'); /* name must have '@'*/ *(nhost++) = '\0'; if (!stralloc_copys(&to,name.s)) die_nomem(); /* local */ if (!stralloc_append(&to,'-')) die_nomem(); /* - */ if (!stralloc_cats(&to,action)) die_nomem(); /* subscribe */ if (!stralloc_append(&to,'-')) die_nomem(); /* - */ if (target.s[i = str_rchr(target.s,'@')]) target.s[i] = '='; if (!stralloc_cats(&to,target.s)) die_nomem(); /* target */ if (!stralloc_append(&to,'@')) die_nomem(); /* - */ if (!stralloc_cats(&to,nhost)) die_nomem(); /* host */ if (!stralloc_0(&to)) die_nomem(); dtline = env_get("DTLINE"); if (!dtline) strerr_die2x(100,FATAL,MSG(ERR_NODTLINE)); if (qmail_open(&qq) == -1) strerr_die2sys(111,FATAL,MSG(ERR_QMAIL_QUEUE)); qmail_puts(&qq,dtline); /* delivered-to */ if (qmail_copy(&qq,subfdin,0) != 0) strerr_die2sys(111,FATAL,MSG(ERR_READ_INPUT)); qmail_from(&qq,from.s); qmail_to(&qq,to.s); if (*(err = qmail_close(&qq)) != '\0') strerr_die4x(111,FATAL,MSG(ERR_TMP_QMAIL_QUEUE),": ",err + 1); strnum[fmt_ulong(strnum,qmail_qp(&qq))] = 0; strerr_die3x(99,INFO,"qp ",strnum); } _exit(0); } else { for (;;) { if (getln(subfdin,&line,&match,'\n') == -1) strerr_die2sys(111,FATAL,MSG(ERR_READ_INPUT)); if (!match) break; if (line.len == 1) continue; /* ignore blank lines */ if (line.s[0] == '#') continue; /* ignore comments */ if (!stralloc_copy(&target,&line)) die_nomem(); target.s[target.len - 1] = '\0'; (void) findname(); if (!stralloc_cats(&name,": ")) die_nomem(); if (!stralloc_cats(&name,target.s)) die_nomem(); if (!stralloc_append(&name,'\n')) die_nomem(); if (substdio_put(subfdout,name.s,name.len) == -1) strerr_die2sys(111,FATAL,MSG(ERR_WRITE_STDOUT)); } if (substdio_flush(subfdout) == -1) strerr_die2sys(111,FATAL,MSG(ERR_FLUSH_STDOUT)); _exit(0); } (void)argc; }