void didentd_init() { char *x; unsigned long id; x = env_get("ROOT"); if (!x) strerr_die2x(111,FATAL,"$ROOT not set"); if (chdir(x) == -1) strerr_die4sys(111,FATAL,"unable to chdir to ",x,": "); x = env_get("GID"); if (!x) strerr_die2x(111,FATAL,"$GID not set"); scan_ulong(x,&id); if (prot_gid((int) id) == -1) strerr_die2sys(111,FATAL,"unable to setgid: "); x = env_get("UID"); if (!x) strerr_die2x(111,FATAL,"$UID not set"); scan_ulong(x,&id); if (prot_uid((int) id) == -1) strerr_die2sys(111,FATAL,"unable to setuid: "); }
void didentd_init() { /* chroot() to /proc/net/ and switch to $UID:$GID */ char *x; unsigned long id; if (chdir("/proc/net/") == -1) strerr_die2sys(111,FATAL,"unable to chdir to '/proc/net/': "); if (chroot(".") == -1) strerr_die2sys(111,FATAL,"unable to chdir to '/proc/net/': "); x = env_get("GID"); if (!x) strerr_die2x(111,FATAL,"$GID not set"); scan_ulong(x,&id); if (prot_gid((int) id) == -1) strerr_die2sys(111,FATAL,"unable to setgid: "); x = env_get("UID"); if (!x) strerr_die2x(111,FATAL,"$UID not set"); scan_ulong(x,&id); if (prot_uid((int) id) == -1) strerr_die2sys(111,FATAL,"unable to setuid: "); }
static int parsetime(const char*c,struct tm* x) { unsigned long tmp; c+=scan_ulong(c,&tmp); x->tm_hour=tmp; if (*c!=':') return -1; ++c; c+=scan_ulong(c,&tmp); x->tm_min=tmp; if (*c!=':') return -1; ++c; c+=scan_ulong(c,&tmp); x->tm_sec=tmp; if (*c!=' ') return -1; return 0; }
static int pls_reader(playlist* pl) { int ret; static playlist_entry entry; buffer* inbuf = pl->ptr; stralloc line; stralloc_init(&line); if(( ret = buffer_getline_sa(inbuf, &line))) { size_t index2, index; index2 = index = 0; while(line.len > 1 && (line.s[line.len - 1] == '\r' || line.s[line.len - 1] == '\n')) line.len--; stralloc_0(&line); if(!str_diffn(&line.s[index], "Number", 6)) { } else if(line.s[index] == '[') { } else if((index2 = str_chr(&line.s[index], '=')) > 0) { unsigned long trackno = 0; index = index2; index2++; do { index--; } while(isdigit(line.s[index]) && index > 0); scan_ulong(&line.s[index], &trackno); if(!str_diffn(&line.s[index], "File", 4)) { stralloc_copys(&entry.path, &line.s[index2]); stralloc_0(&entry.path); } else if(!str_diffn(&line.s[index], "Title", 5)) { stralloc_copys(&entry.title, &line.s[index2]); stralloc_0(&entry.title); } else if(!str_diffn(&line.s[index], "Length", 6)) { unsigned long len; scan_ulong(&line.s[index2], &len); entry.length = len; } /* uint32 index = 8; index += scan_ulong(&line.s[index], &len); entry.length = len; index++; stralloc_copys(&entry.title, &line.s[index]); stralloc_0(&entry.title); */ } else { /* stralloc_copy(&entry.path, &line); stralloc_0(&entry.path); if(pl->callback) { pl->callback(pl, &entry.title, &entry.path, entry.length); }*/ } } return ret; }
const char *get_from(const char *adr, /* target address */ const char *act) /* action */ /* If we captured a from line, it will be from the subscriber, except */ /* when -S is used when it's usually from the subscriber, but of course */ /* could be from anyone. The matching to stored data is required only */ /* to support moderated lists, and in cases where a new -sc is issued */ /* because an old one was invalid. In this case, we read through the */ /* from file trying to match up a timestamp with that starting in */ /* *(act+3). If the time stamp matches, we compare the target address */ /* itself. act + 3 must be a legal part of the string returns pointer to*/ /* fromline, NULL if not found. Since the execution time from when to */ /* storage may differ, we can't assume that the timestamps are in order.*/ { int fd; const char *fl; unsigned int pos; unsigned long thistime; unsigned long linetime; if (!flagstorefrom) return 0; if (fromline.len) { /* easy! We got it in this message */ stralloc_0(&fromline); return fromline.s; } /* need to recover it from DIR/from */ fl = 0; (void) scan_ulong(act+3,&thistime); if ((fd = open_read("from")) == -1) { if (errno == error_noent) return 0; else strerr_die2sys(111,FATAL,MSG1(ERR_READ,"from")); } substdio_fdbuf(&sstext,read,fd,textbuf,(int) sizeof(textbuf)); for (;;) { if (getln(&sstext,&fromline,&match,'\n') == -1) strerr_die2sys(111,FATAL,MSG1(ERR_READ,"from")); if (!match) break; fromline.s[fromline.len - 1] = (char) 0; /* now:time addr\0fromline\0 read all. They can be out of order! */ pos = scan_ulong(fromline.s,&linetime); if (linetime != thistime) continue; if (!str_diff(fromline.s + pos + 1,adr)) { pos = str_len(fromline.s); if (pos < fromline.len) { fl = fromline.s + pos + 1; break; } } } close(fd); return fl; }
void main(int argc,char **argv) { int fdlock; unsigned long delay; (void) umask(022); sig_pipeignore(); when = now(); getconfopt(argc,argv,options,1,0); if (flagreturn < 0) /* default to returning timed-out messages */ flagreturn = !getconf_isset("noreturnposts"); getconf_line(&modtime,"modtime",0); if (!stralloc_0(&modtime)) die_nomem(); scan_ulong(modtime.s,&delay); if (!delay) delay = DELAY_DEFAULT; else if (delay < DELAY_MIN) delay = DELAY_MIN; else if (delay > DELAY_MAX) delay = DELAY_MAX; older = (unsigned long) when - 3600L * delay; /* delay is in hours */ fdlock = lockfile("mod/lock"); dodir("mod/pending/",flagreturn); dodir("mod/accepted/",0); dodir("mod/rejected/",0); dodir("mod/unconfirmed/",0); _exit(0); }
size_t scan_uint(const char* src, unsigned int* dest) { if(sizeof(unsigned int) == sizeof(unsigned long)) { /* a good optimizing compiler should remove the else clause when not * needed */ return scan_ulong(src, (unsigned long*)dest); } else if(sizeof(unsigned int) < sizeof(unsigned long)) { const char* cur; unsigned int l; for(cur = src, l = 0; *cur >= '0' && *cur <= '9'; ++cur) { unsigned long tmp = l * 10ul + *cur - '0'; if((unsigned int)tmp != tmp) break; l = tmp; } if(cur > src) *dest = l; return (size_t)(cur - src); #ifdef __GNUC__ } else { /* the C standard says that sizeof(short) <= sizeof(unsigned int) <= * sizeof(unsigned long); this can never happen. Provoke a compile * error if it does */ char compileerror[sizeof(unsigned long) - sizeof(unsigned int)]; (void)compileerror; #endif } }
void getlarg(long *l) { unsigned long ul; if (str_equal(optarg, "=")) { *l =-1; return; } if (optarg[scan_ulong(optarg, &ul)]) usage(); *l =ul; }
unsigned int ip4_scan(const char *s,unsigned char ip[4]) { unsigned int i; unsigned int len; unsigned long u; len = 0; i = scan_ulong(s,&u); if (!i) return 0; ip[0] = u; s += i; len += i; if (*s != '.') return 0; ++s; ++len; i = scan_ulong(s,&u); if (!i) return 0; ip[1] = u; s += i; len += i; if (*s != '.') return 0; ++s; ++len; i = scan_ulong(s,&u); if (!i) return 0; ip[2] = u; s += i; len += i; if (*s != '.') return 0; ++s; ++len; i = scan_ulong(s,&u); if (!i) return 0; ip[3] = u; s += i; len += i; return len; }
static void do_get(const char *action) { unsigned long u; struct stat st; char ch; int r; unsigned int pos; int fd; if (!flagget) strerr_die2x(100,FATAL,MSG(ERR_NOT_AVAILABLE)); hdr_subject(MSG(SUB_GET_MSG)); hdr_ctboundary(); copy(&qq,"text/top",flagcd); pos = str_len(ACTION_GET); if (!case_starts(action,ACTION_GET)) pos = str_len(ALT_GET); if (action[pos] == '.' || action [pos] == '_') pos++; scan_ulong(action + pos,&u); stralloc_copys(&line,"archive/"); stralloc_catb(&line,strnum,fmt_ulong(strnum,u / 100)); stralloc_cats(&line,"/"); stralloc_catb(&line,strnum,fmt_uint0(strnum,(unsigned int) (u % 100),2)); stralloc_0(&line); fd = open_read(line.s); if (fd == -1) if (errno != error_noent) strerr_die2sys(111,FATAL,MSG1(ERR_OPEN,line.s)); else copy_act("text/get-bad"); else { if (fstat(fd,&st) == -1) copy_act("text/get-bad"); else if (!(st.st_mode & 0100)) copy_act("text/get-bad"); else { showsend("get"); substdio_fdbuf(&sstext,read,fd,textbuf,sizeof(textbuf)); qmail_puts(&qq,"> "); for (;;) { r = substdio_get(&sstext,&ch,1); if (r == -1) strerr_die2sys(111,FATAL,MSG1(ERR_READ,line.s)); if (r == 0) break; qmail_put(&qq,&ch,1); if (ch == '\n') qmail_puts(&qq,"> "); } qmail_puts(&qq,"\n"); } close(fd); } copybottom(0); qmail_to(&qq,target.s); }
void c_init(char **script) { int i; struct cyclog *d; char *processor; unsigned long num; unsigned long size; cnum = 0; for (i = 0;script[i];++i) if ((script[i][0] == '.') || (script[i][0] == '/')) ++cnum; c = (struct cyclog *) alloc(cnum * sizeof(*c)); if (!c) strerr_die2x(111,FATAL,"out of memory"); d = c; processor = 0; num = 10; size = 99999; for (i = 0;script[i];++i) if (script[i][0] == 's') { scan_ulong(script[i] + 1,&size); if (size < 4096) size = 4096; if (size > 16777215) size = 16777215; } else if (script[i][0] == 'n') { scan_ulong(script[i] + 1,&num); if (num < 2) num = 2; } else if (script[i][0] == '!') { processor = script[i] + 1; } else if ((script[i][0] == '.') || (script[i][0] == '/')) { d->num = num; d->size = size; d->processor = processor; d->dir = script[i]; buffer_init(&d->ss,c_write,d - c,d->buf,sizeof d->buf); restart(d); ++d; } }
unsigned int scan_ushort(char *s, unsigned short *u) { unsigned long l; unsigned int r; r = scan_ulong(s, &l); *u = l; return r; }
unsigned int scan_uint(const char *s, unsigned int *up) { unsigned long ul; unsigned int ui; unsigned int len; len = scan_ulong(s, &ul); if (!len) return 0; ui = (unsigned int) ul; *up = ui; return len; }
unsigned int scan_long(register const char* s,register long* i) { int sign; unsigned long u; register unsigned int len; len = scan_plusminus(s,&sign); s += len; len += scan_ulong(s,&u); if (sign < 0) *i = -u; else *i = u; return len; }
void log_init(int fd, unsigned long mask, int via_spawn) /* * Known LOGLEVELs: */ { char *a = env_get("LOGLEVEL"); loglevel = 0; addLOG = via_spawn; if ( a && *a ) { scan_ulong(a, &loglevel); } else if ((a = env_get("DEBUGLEVEL")) && *a ) { scan_ulong(a, &loglevel); } loglevel &= mask; substdio_fdbuf(&sslog, subwrite, fd, logbuffer, sizeof(logbuffer) ); /* logit(4, "LOGLEVEL set to %i\n", loglevel); */ }
/* Searches the subscriber log and outputs via subwrite(s,len) any entry * that matches search. A '_' is search is a wildcard. Any other * non-alphanum/'.' char is replaced by a '_'. */ static void _searchlog(struct subdbinfo *info, const char *table, char *search, /* search string */ int subwrite()) /* output fxn */ { sqlite3_stmt *stmt; int res; datetime_sec when; struct datetime dt; char date[DATE822FMT]; /* SELECT (*) FROM list_slog WHERE fromline LIKE '%search%' OR address */ /* LIKE '%search%' ORDER BY tai; */ /* The '*' is formatted to look like the output of the non-mysql version */ /* This requires reading the entire table, since search fields are not */ /* indexed, but this is a rare query and time is not of the essence. */ if (!stralloc_copys(&line,"SELECT tai, edir||etype||' '||address||' '||fromline" " FROM ")) die_nomem(); if (!stralloc_cat_table(&line,info,table)) die_nomem(); if (!stralloc_cats(&line,"_slog")) die_nomem(); if (*search) { /* We can afford to wait for LIKE '%xx%' */ if (!stralloc_cats(&line," WHERE fromline LIKE '%")) die_nomem(); if (!stralloc_cats(&line,search)) die_nomem(); if (!stralloc_cats(&line,"%' OR address LIKE '%")) die_nomem(); if (!stralloc_cats(&line,search)) die_nomem(); if (!stralloc_cats(&line,"%'")) die_nomem(); } /* ordering by tai which is an index */ if (!stralloc_cats(&line," ORDER by tai")) die_nomem(); if (!stralloc_0(&line)) die_nomem(); if ((stmt = _sqlquery(info, &line)) == NULL) strerr_die2x(111,FATAL,sqlite3_errmsg((sqlite3*)info->conn)); while ((res = sqlite3_step(stmt)) != SQLITE_DONE) { if (res != SQLITE_ROW) strerr_die2x(111,FATAL,sqlite3_errmsg((sqlite3*)info->conn)); (void)scan_ulong((const char*)sqlite3_column_text(stmt,0),&when); datetime_tai(&dt,when); if (!stralloc_copyb(&line,date,date822fmt(date,&dt)-1)) die_nomem(); if (!stralloc_cats(&line,": ")) die_nomem(); if (!stralloc_catb(&line,strnum,fmt_ulong(strnum,when))) die_nomem(); if (!stralloc_cats(&line," ")) die_nomem(); if (!stralloc_catb(&line, (const char*)sqlite3_column_text(stmt,1), sqlite3_column_bytes(stmt,1))) die_nomem(); if (subwrite(line.s,line.len) == -1) die_write(); } sqlite3_finalize(stmt); }
unsigned int scan_uchar(const char *s, unsigned char *up) { unsigned long ul; unsigned int len; unsigned char uc; len = scan_ulong(s, &ul); if (!len) return 0; uc = (unsigned char) ul; *up = uc; return len; }
unsigned int ipsvd_scan_port(const char *s, const char *proto, unsigned long *p) { struct servent *se; if (! *s) return(0); if ((se =getservbyname(s, proto))) { /* what is se->s_port, uint16 or uint32? */ *p =htons(se->s_port); return(1); } if (s[scan_ulong(s, p)]) return(0); return(1); }
int control_readint(int *i,char *fn) { unsigned long u; switch(control_readline(&line,fn)) { case 0: return 0; case -1: return -1; } if (!stralloc_0(&line)) return -1; if (!scan_ulong(line.s,&u)) return 0; *i = u; return 1; }
/* Searches the subscriber log and outputs via subwrite(s,len) any entry * that matches search. A '_' is search is a wildcard. Any other * non-alphanum/'.' char is replaced by a '_'. */ void sub_sql_searchlog(struct subdbinfo *info, const char *table, char *search, /* search string */ int subwrite()) /* output fxn */ { void *result; datetime_sec when; struct datetime dt; char date[DATE822FMT]; int nparams; char strnum[FMT_ULONG]; make_name(info,table?"_":0,table,0); /* SELECT (*) FROM list_slog WHERE fromline LIKE '%search%' OR address */ /* LIKE '%search%' ORDER BY tai; */ /* The '*' is formatted to look like the output of the non-mysql version */ /* This requires reading the entire table, since search fields are not */ /* indexed, but this is a rare query and time is not of the essence. */ stralloc_copys(&query,"SELECT "); stralloc_cats(&query,sql_searchlog_select_defn); stralloc_cats(&query," FROM "); stralloc_cat(&query,&name); stralloc_cats(&query,"_slog"); if (*search) { /* We can afford to wait for LIKE '%xx%' */ stralloc_copys(¶ms[0],search); stralloc_copys(¶ms[1],search); nparams = 2; stralloc_cats(&query," WHERE "); stralloc_cats(&query,sql_searchlog_where_defn); } else nparams = 0; /* ordering by tai which is an index */ stralloc_cats(&query," ORDER by tai"); result = sql_select(info,&query,nparams,params); while (sql_fetch_row(info,result,2,params)) { stralloc_0(¶ms[0]); (void)scan_ulong(params[0].s,&when); datetime_tai(&dt,when); stralloc_copyb(¶ms[0],date,date822fmt(date,&dt)-1); stralloc_cats(¶ms[0],": "); stralloc_catb(¶ms[0],strnum,fmt_ulong(strnum,when)); stralloc_cats(¶ms[0]," "); stralloc_cat(¶ms[0],¶ms[1]); if (subwrite(params[0].s,params[0].len) == -1) die_write(); } sql_free_result(info,result); }
void dodir(const char *dirname,int reply) /* parses file names in directory 'dirname'. Files that are not owner */ /* writable (w) are ignored. If the files are older (by name!) than */ /* now-delay, action is taken: */ /* If the owner x bit is not set, the file is erased. */ /* If it is set and reply is not set, the file is erased. If both are */ /* set, a notice about the timeout is sent to the poster. If this */ /* fails due to a message-related error (format, etc) the file is */ /* erased even though no notice is sent. For temporary errors (like */ /* out-of-memory) the message is left intact for the next run. If the */ /* notice is sent successfully, the file is erased. All this is to */ /* do the best possible without risking a rerun of the .qmail file, */ /* which could result in a redelivery of the action request and a */ /* second (incorrect) reply to the moderator's request. */ /* NOTE: ALL non-hidden files in this dir are processed and merci- */ /* lessly deleted. No checks for proper file name. E.g. 'HELLO' */ /* => time 0 => will be deleted on the next ezmlm-clean run. */ { DIR *moddir; direntry *d; unsigned long modtime; struct stat st; moddir = opendir(dirname); if (!moddir) strerr_die2sys(0,FATAL,MSG1(ERR_OPEN,dirname)); while ((d = readdir(moddir))) { if (d->d_name[0] == '.') continue; scan_ulong(d->d_name,&modtime); if (modtime < older) { if (!stralloc_copys(&fnmsg,dirname)) die_nomem(); if (!stralloc_cats(&fnmsg,d->d_name)) die_nomem(); if (!stralloc_0(&fnmsg)) die_nomem(); if((stat(fnmsg.s,&st) != -1) && (st.st_mode & 0200)) { if(reply && (st.st_mode & 0100)) { /* unlink unless there was a TEMPORARY */ /* not message-related error notifying */ /* poster and msg x bit set. Leave r/o*/ /* messages alone. Non-x bit msg are */ /* trash. Just unlink, don't notify */ sendnotice(fnmsg.s); unlink(fnmsg.s); } else unlink(fnmsg.s); } } } closedir(moddir); }
/* uid:gid[:gid[:gid]...] */ unsigned int uidgids_set(struct uidgid *u, char *ug) { unsigned long id; int i; if (*(ug +=scan_ulong(ug, &id)) != ':') return(0); u->uid =(uid_t)id; ++ug; for (i =0; i < 60; ++i, ++ug) { ug +=scan_ulong(ug, &id); u->gid[i] =(gid_t)id; if (*ug != ':') { ++i; break; } } u->gid[i] =0; u->gids =i; if (*ug) return(0); return(1); }
int qldap_get_ulong(qldap *q, const char *attr, unsigned long *ul) { unsigned long ulval; int r; r = qldap_get_attr(q, attr, &ldap_attr, SINGLE_VALUE); if (r == OK) { if (ldap_attr.s[scan_ulong(ldap_attr.s, &ulval)] != '\0') return BADVAL; *ul = ulval; } return r; }
void store_from(stralloc *frl, /* from line */ const char *adr) /* rewrites the from file removing all that is older than 1000000 secs */ /* and add the curent from line (frl). Forget it if there is none there.*/ /* NOTE: This is used only for subscribes to moderated lists! */ { int fdin; int fdout; unsigned long linetime; if (!flagstorefrom || !frl->len) return; /* nothing to store */ lock(); if ((fdout = open_trunc("fromn")) == -1) strerr_die2sys(111,FATAL,MSG1(ERR_OPEN,"fromn")); substdio_fdbuf(&ssfrom,write,fdout,frombuf,(int) sizeof(frombuf)); if ((fdin = open_read("from")) == -1) { if (errno != error_noent) strerr_die2sys(111,FATAL,MSG1(ERR_OPEN,"from")); } else { substdio_fdbuf(&sstext,read,fdin,textbuf,(int) sizeof(textbuf)); for (;;) { if (getln(&sstext,&line,&match,'\n') == -1) strerr_die2sys(111,FATAL,MSG1(ERR_READ,"from")); if (!match) break; (void) scan_ulong(line.s,&linetime); if (linetime + 1000000 > (unsigned long) when && linetime <= (unsigned long) when) if (substdio_bput(&ssfrom,line.s,line.len)) strerr_die2sys(111,FATAL,MSG1(ERR_WRITE,"fromn")); } close(fdin); } /* build new entry */ stralloc_copyb(&line,strnum,fmt_ulong(strnum,when)); stralloc_append(&line,' '); stralloc_cats(&line,adr); stralloc_0(&line); stralloc_catb(&line,frl->s,frl->len); stralloc_append(&line,'\n'); if (substdio_bput(&ssfrom,line.s,line.len) == -1) strerr_die2sys(111,FATAL,MSG1(ERR_WRITE,"fromn")); if (substdio_flush(&ssfrom) == -1) strerr_die2sys(111,FATAL,MSG1(ERR_WRITE,"fromn")); if (fsync(fdout) == -1) strerr_die2sys(111,FATAL,MSG1(ERR_SYNC,"fromn")); if (close(fdout) == -1) strerr_die2sys(111,FATAL,MSG1(ERR_CLOSE,"fromn")); wrap_rename("fromn","from"); unlock(); }
int main() { char *buf; unsigned long bufval; unsigned long ul; if (sizeof(unsigned long) == 8) { buf = "18446744073709551615"; bufval = 18446744073709551615UL; } else { buf = "4294967295"; bufval = 4294967295UL; } scan_ulong(&ul, buf); if (ul != bufval) return 1; buf = "123abc"; scan_ulong(&ul, buf); if (ul != 123) return 2; return 0; }
void ipprefix_cat(stralloc *out,char *s) { unsigned long u; char ch; unsigned int j; for (;;) if (*s == '.') ++s; else { j = scan_ulong(s,&u); if (!j) return; s += j; ch = u; if (!stralloc_catb(out,&ch,1)) nomem(); } }
int main() { char buf[1024]; unsigned long long int i; if (sizeof(unsigned long) != 4) return 0; for (i=1; i<0xfffffffffull; i+=i+1) { int k; unsigned long test; buf[k=fmt_ulonglong(buf,i)]=0; buffer_puts(buffer_1,buf); buffer_putnlflush(buffer_1); if (buf[scan_ulong(buf,&test)]) /* scan did not like the whole number */ assert(i>0xffffffffull); else assert(i<=0xffffffffull); } return 0; }
int hashok(const char *action,const char *ac) { const char *x; datetime_sec u; x = action + 3; x += scan_ulong(x,&u); hashdate = u; if (hashdate > when) return 0; if (hashdate + 1000000 < when) return 0; u = hashdate; strnum[fmt_ulong(strnum,(unsigned long) u)] = 0; cookie(hash,key.s,key.len - flagdig,strnum,target.s,ac); if (*x == '.') ++x; if (str_len(x) != COOKIE) return 0; return byte_equal(hash,COOKIE,x); }
size_t scan_ip4(void *ip, char *str) { unsigned int i; size_t r; const char *start = str; unsigned long u; for (i = 0; i < 4; ++i) { r = scan_ulong(&u, str); if (r == 0) return 0; str += r; ((char *)ip)[i] = u; if ((i < 3) && (*str++ != '.')) return 0; } return str - start; }
int main(int argc,char **argv) { int fd; unsigned long loop; if (!*argv) _exit(0); if (!*++argv) _exit(0); scan_ulong(*argv,&loop); if (cdb_make_start(&c,1) == -1) die_write(); while (loop) { uint32_pack(key,--loop); if (cdb_make_add(&c,key,4,data,sizeof data) == -1) die_write(); } if (cdb_make_finish(&c) == -1) die_write(); _exit(0); }