예제 #1
0
void startprocessor(struct cyclog *d)
{
  const char *args[4];
  int fd;

  sig_uncatch(sig_term);
  sig_uncatch(sig_alarm);
  sig_unblock(sig_term);
  sig_unblock(sig_alarm);

  fd = open_read("previous");
  if (fd == -1) return;
  if (fd_move(0,fd) == -1) return;
  fd = open_trunc("processed");
  if (fd == -1) return;
  if (fd_move(1,fd) == -1) return;
  fd = open_read("state");
  if (fd == -1) return;
  if (fd_move(4,fd) == -1) return;
  fd = open_trunc("newstate");
  if (fd == -1) return;
  if (fd_move(5,fd) == -1) return;

  args[0] = "sh";
  args[1] = "-c";
  args[2] = d->processor;
  args[3] = 0;
  execve("/bin/sh",args,environ);
}
예제 #2
0
파일: ezmlm-get.c 프로젝트: abh/ezmlm-idx
void write_ulong(unsigned long num,unsigned long cum,unsigned long dat,
		 const char *fn,const char *fnn)
/* write num to "fnn" add ':' & cum if cum <>0, then move "fnn" to "fn" */
{
  int fd;

  fd = open_trunc(fnn);
  if (fd == -1)
     strerr_die2sys(111,FATAL,MSG1(ERR_CREATE,fnn));
  substdio_fdbuf(&ssnum,write,fd,numbuf,sizeof(numbuf));
  if (substdio_put(&ssnum,strnum,fmt_ulong(strnum,num)) == -1)
     strerr_die2sys(111,FATAL,MSG1(ERR_WRITE,fnn));
  if (substdio_puts(&ssnum,":") == -1)
     strerr_die2sys(111,FATAL,MSG1(ERR_WRITE,fnn));
  if (substdio_put(&ssnum,strnum,fmt_ulong(strnum,cum)) == -1)
     strerr_die2sys(111,FATAL,MSG1(ERR_WRITE,fnn));
  if (dat) {
    if (substdio_puts(&ssnum,":") == -1)
       strerr_die2sys(111,FATAL,MSG1(ERR_WRITE,fnn));
    if (substdio_put(&ssnum,strnum,fmt_ulong(strnum,dat)) == -1)
       strerr_die2sys(111,FATAL,MSG1(ERR_WRITE,fnn));
  }
  if (substdio_puts(&ssnum,"\n") == -1)
     strerr_die2sys(111,FATAL,MSG1(ERR_WRITE,fnn));
  if (substdio_flush(&ssnum) == -1)
     strerr_die2sys(111,FATAL,MSG1(ERR_FLUSH,fnn));
  if (fsync(fd) == -1)
     strerr_die2sys(111,FATAL,MSG1(ERR_SYNC,fnn));
  if (close(fd) == -1)
     strerr_die2sys(111,FATAL,MSG1(ERR_CLOSE,fnn));
  wrap_rename(fnn,fn);
}
예제 #3
0
void start(const char *s)
{
  fn = s;
  fd = open_trunc(fn);
  if (fd == -1) fail();
  buffer_init(&ss,buffer_unixwrite,fd,buf,sizeof buf);
}
예제 #4
0
void announce(void)
{
  int fd;
  int r;

  status[16] = (pid ? flagpaused : 0);
  status[17] = (flagwant ? (flagwantup ? 'u' : 'd') : 0);

  fd = open_trunc("supervise/status.new");
  if (fd == -1) {
    strerr_warn4(WARNING,"unable to open ",dir,"/supervise/status.new: ",&strerr_sys);
    return;
  }

  r = write(fd,status,sizeof status);
  if (r == -1) {
    strerr_warn4(WARNING,"unable to write ",dir,"/supervise/status.new: ",&strerr_sys);
    close(fd);
    return;
  }
  close(fd);
  if (r < sizeof status) {
    strerr_warn4(WARNING,"unable to write ",dir,"/supervise/status.new: partial write",0);
    return;
  }

  if (rename("supervise/status.new","supervise/status") == -1)
    strerr_warn4(WARNING,"unable to rename ",dir,"/supervise/status.new to status: ",&strerr_sys);
}
예제 #5
0
void snap_dump(char *filename, stralloc *sa)
{
  dAVLCursor c;
  dAVLNode *node;
  char strip[IP6_FMT];
  char strnum[FMT_ULONG];
  int fd;

  fd = open_trunc("filename");  
  if(fd == -1)
    strerr_warn1(ARGV0 "warning: unable to open for tcp.tmp for writing", &strerr_sys);
  
  buffer_init(&wb, write, fd, wbspace, sizeof wbspace);

  node = dAVLFirst(&c, t);
  while(node)
    {
      buffer_put(&wb, strnum, fmt_ulong(strnum, node->key));
      buffer_puts(&wb, ",");
      buffer_put(&wb, strip, ip4_fmt(strip, node->ip4));
      buffer_puts(&wb, ",");
      buffer_put(&wb, strip, ip6_fmt(strip, node->ip6));
      buffer_puts(&wb, ",LOC\n");
      
      node = dAVLNext(&c);
    }
 
  buffer_flush(&wb);
  close(fd);
}
예제 #6
0
int main() {
  int fd = open_trunc("trunc.txt");
  if (fd == -1)
    return 1;
    
  return 0;
}
예제 #7
0
static void announce()
{
	int fd;
	int r;

	status[12] = (pid ? flagpaused : 0);
	status[13] = (flagwant ? (flagwantup ? 'u' : 'd') : 0);
	status[14] = (closealarm ? 'x' : 'o');
	status[15] = 0;

	fd = open_trunc(status_files[4]);
	if (fd == -1)
	{
		write_log(fdlogwf, WARNING, "unable to open ", status_dir, "/status.new\n");
		return;
	}

	r = write(fd, status, sizeof status);
	if (r == -1)
	{
		write_log(fdlogwf, WARNING, "unable to write ", status_dir, "/status.new\n");
		close(fd);
		return;
	}
	close(fd);
	if (r < sizeof status)
	{
		write_log(fdlogwf, WARNING, "unable to write ", status_dir, "/status.new: partial write\n");
		return;
	}

	if (rename(status_files[4], status_files[3]) == -1)
		write_log(fdlogwf, WARNING, "unable to rename ", status_dir, "/status.new to status\n");
}
예제 #8
0
파일: runsv.c 프로젝트: Predator-SD/Tarixy
static int open_trunc_or_warn(const char *name)
{
	int fd = open_trunc(name);
	if (fd < 0)
		bb_perror_msg("%s: warning: cannot open %s",
				dir, name);
	return fd;
}
예제 #9
0
void f_open(const char *slash)
{
  int fd;

  dirplusmake(slash);
  fd = open_trunc(dirplus.s);
  if (fd == -1)
    strerr_die2sys(111,FATAL,MSG1(ERR_CREATE,dirplus.s));

  substdio_fdbuf(&ss,write,fd,ssbuf,sizeof(ssbuf));
}
예제 #10
0
int sv_stat_save(char *path, sv_stat_t *svst) {
  int fd;
  array_t new_path = ARRAY_INIT(1);
  int r;
  char status[SUPERVISE_STATUS_SIZE];
  uint32_t tmp;
  
  /* Pack the svstat data into the status byte array. */
  taia_pack(status, &svst->timestamp);
  tmp = svst->pid;
  ((uint32_t *)status)[3] = htobe32(tmp);
  status[16] = svst->paused;
  status[17] = svst->mode;
  
  /* Construct the path for the .new file into the array which *MUST* be freed
   * before returning. */
  array_append(&new_path, path, strlen(path));
  array_append(&new_path, SUPERVISE_STATUS_NEW_EXT, strlen(SUPERVISE_STATUS_NEW_EXT));
  array_append_null(&new_path);
  if (array_failed(&new_path)) {
    array_reset(&new_path);
    errno = ENOMEM;
    return -1;
  }
  
  /* Open the tmp file, write the status byte array to it, verify the entire
   * array was written, and finally rename it to status. */
  fd = open_trunc(array_start(&new_path));
  if (fd == -1) {
    array_reset(&new_path);
    return ESVOPENSTATNEW;
  }
  
  r = write(fd, status, SUPERVISE_STATUS_SIZE);
  if ((r == -1) || (r != SUPERVISE_STATUS_SIZE)) {
    close(fd);
    array_reset(&new_path);
    return ESVWRITESTATNEW;
  }
  close(fd);
  
  if (rename(array_start(&new_path), path) == -1) {
    array_reset(&new_path);
    return ESVWRITESTAT;
  }
  
  array_reset(&new_path);
  return 0;
}
예제 #11
0
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();
}
예제 #12
0
void numwrite(void)
{
  int fd;
  int i;

  i = fmt_ulong(strnum,msgnum);
  strnum[i++] = ':';
  i += fmt_ulong(strnum+i,cumsize);
  strnum[i++] = '\n';

  if ((fd = open_trunc("numnew")) == -1
      || write(fd, strnum, i) != i
      || fsync(fd) == -1
      || close(fd) == -1)
    strerr_die2sys(111,FATAL,MSG1(ERR_CREATE,"numnew"));
  wrap_rename("numnew","num");
}
예제 #13
0
int main() {
  int fd = open_read("read.txt");
  if (fd != -1)
    return 1;
    
  fd = open_trunc("read.txt");
  if (fd == -1)
    return 2;
    
  close(fd);
  
  fd = open_read("read.txt");
  if (fd == -1)
    return 3;
    
  return 0;
}
예제 #14
0
static int openone(unsigned long outnum)
{
  static stralloc fnadir = {0};
  char strnum[FMT_ULONG];
  int fd;
  stralloc_copys(&fnadir,"archive/");
  stralloc_catb(&fnadir,strnum,fmt_ulong(strnum,outnum / 100));
  stralloc_copy(&fnaf,&fnadir);
  stralloc_cats(&fnaf,"/");
  stralloc_catb(&fnaf,strnum,fmt_uint0(strnum,(unsigned int)(outnum % 100),2));
  stralloc_0(&fnadir);
  stralloc_0(&fnaf);

  if (mkdir(fnadir.s,0755) == -1)
    if (errno != error_exist)
      strerr_die2sys(111,FATAL,MSG1(ERR_CREATE,fnadir.s));
  if ((fd = open_trunc(fnaf.s)) == -1)
    strerr_die2sys(111,FATAL,MSG1(ERR_WRITE,fnaf.s));

  substdio_fdbuf(&ssarchive,write,fd,archivebuf,sizeof archivebuf);
  return fd;
}
예제 #15
0
int main()
{
  umask(033);
  if (chdir(auto_qmail) == -1)
    strerr_die4sys(111,FATAL,"unable to chdir to ",auto_qmail,": ");

  fd = open_read("control/morercpthosts");
  if (fd == -1) die_read();

  substdio_fdbuf(&ssin,read,fd,inbuf,sizeof inbuf);

  fdtemp = open_trunc("control/morercpthosts.tmp");
  if (fdtemp == -1) die_write();

  if (cdbmss_start(&cdbmss,fdtemp) == -1) die_write();

  for (;;) {
    if (getln(&ssin,&line,&match,'\n') != 0) die_read();
    case_lowerb(line.s,line.len);
    while (line.len) {
      if (line.s[line.len - 1] == ' ') { --line.len; continue; }
      if (line.s[line.len - 1] == '\n') { --line.len; continue; }
      if (line.s[line.len - 1] == '\t') { --line.len; continue; }
      if (line.s[0] != '#')
	if (cdbmss_add(&cdbmss,line.s,line.len,"",0) == -1)
	  die_write();
      break;
    }
    if (!match) break;
  }

  if (cdbmss_finish(&cdbmss) == -1) die_write();
  if (fsync(fdtemp) == -1) die_write();
  if (close(fdtemp) == -1) die_write(); /* NFS stupidity */
  if (rename("control/morercpthosts.tmp","control/morercpthosts.cdb") == -1)
    strerr_die2sys(111,FATAL,"unable to move control/morercpthosts.tmp to control/morercpthosts.cdb");

  _exit(0);
}
예제 #16
0
int openwritenclose_unsafe_internal (char const *fn, char const *s, unsigned int len, uint64 *dev, uint64 *ino, int dosync)
{
  struct stat st ;
  int fd = open_trunc(fn) ;
  if (fd < 0) return 0 ;
  if (allwrite(fd, s, len) < len) goto fail ;
  if ((dev || ino) && (fstat(fd, &st) < 0)) goto fail ;
  if (dosync && (fd_sync(fd) < 0) && (errno != EINVAL)) goto fail ;
  fd_close(fd) ;
  if (dev) *dev = (uint64)st.st_dev ;
  if (ino) *ino = (uint64)st.st_ino ;
  return 1 ;

 fail:
  {
    register int e = errno ;
    fd_close(fd) ;
    unlink(fn) ;
    errno = e ;
  }
  return 0 ;
}
예제 #17
0
int openone(unsigned long outnum)
{
  int fd;
  if (!stralloc_copys(&fnadir,"archive/")) die_nomem();
  if (!stralloc_catb(&fnadir,strnum,
		     fmt_ulong(strnum,outnum / 100))) die_nomem();
  if (!stralloc_copy(&fnaf,&fnadir)) die_nomem();
  if (!stralloc_cats(&fnaf,"/")) die_nomem();
  if (!stralloc_catb(&fnaf,strnum,
		     fmt_uint0(strnum,(unsigned int)(outnum % 100),2)))
    die_nomem();
  if (!stralloc_0(&fnadir)) die_nomem();
  if (!stralloc_0(&fnaf)) die_nomem();

  if (mkdir(fnadir.s,0755) == -1)
    if (errno != error_exist)
      strerr_die4sys(111,FATAL,ERR_CREATE,fnadir.s,": ");
  if ((fd = open_trunc(fnaf.s)) == -1)
    strerr_die4sys(111,FATAL,ERR_WRITE,fnaf.s,": ");

  substdio_fdbuf(&ssarchive,write,fd,archivebuf,sizeof archivebuf);
  return fd;
}
예제 #18
0
파일: qmail-cdb.c 프로젝트: ajtulloch/qmail
int main(int argc, char **argv)
{
  umask(033);

  if (argc != 3)
    strerr_die1sys(111,"qmail-cdb: usage: qmail-cdb rules.cdb rules.tmp");

  substdio_fdbuf(&ssin,subread,0,inbuf,sizeof inbuf);

  fdtemp = open_trunc(argv[2]);
  if (fdtemp == -1) die_write(argv[2]);

  if (cdb_make_start(&cdbm,fdtemp) == -1) die_write(argv[2]);

  for (;;) {
    if (getln(&ssin,&line,&match,'\n') != 0) die_read();
    case_lowerb(line.s,line.len);
    while (line.len) {
      if (line.s[line.len - 1] == ' ') { --line.len; continue; }
      if (line.s[line.len - 1] == '\n') { --line.len; continue; }
      if (line.s[line.len - 1] == '\t') { --line.len; continue; }
      if (line.s[0] != '#')
	if (cdb_make_add(&cdbm,line.s,line.len,"",0) == -1)
	  die_write(argv[2]);
      break;
    }
    if (!match) break;
  }

  if (cdb_make_finish(&cdbm) == -1) die_write(argv[2]);
  if (fsync(fdtemp) == -1) die_write(argv[2]);
  if (close(fdtemp) == -1) die_write(argv[2]); /* NFS stupidity */
  if (rename(argv[2],argv[1]) == -1)
    strerr_die5sys(111, FATAL, "unable to move ", argv[2], " to ", argv[1]);

  return 0;
}
예제 #19
0
static void do_ed(char *action)
{
  datetime_sec u;
  int flaggoodfield;
  int fd;
  char *x, *y;
  char *cp,*cplast,*cpnext,*cpafter;
  int flagdone;
  unsigned int len;
  const char *fname;
  unsigned int i;

  x = action + LENGTH_ED;
  x += scan_ulong(x,&u);
  if ((u > when) || (u < when - 100000)) die_cookie();
  if (*x == '.') ++x;
  fname = x;
  x += str_chr(x,'.');
  if (!*x) die_cookie();
  *x = (char) 0;
  ++x;
  stralloc_copys(&fnedit,"text/");
  stralloc_cats(&fnedit,fname);
  stralloc_0(&fnedit);
  y = fnedit.s + 5;		/* after "text/" */
  while (*++y) {		/* Name should be guaranteed by the cookie, */
				/* but better safe than sorry ... */
    if (((*y > 'z') || (*y < 'a')) && (*y != '_'))
      strerr_die2x(100,FATAL,MSG(ERR_BAD_NAME));
    if (*y == '_') *y = '-';
  }

  lock();			/* file must not change while here */

  switch (slurp(fnedit.s,&text,1024)) {
  case -1:
    strerr_die2sys(111,FATAL,MSG1(ERR_READ,fnedit.s));
  case 0:
    strerr_die5x(100,FATAL,dir,"/",fnedit.s,MSG(ERR_NOEXIST));
  }
  stralloc_copy(&line,&text);

  subst_nuls(&line);

  stralloc_cat(&line,&fnedit);	/* including '\0' */
  strnum[fmt_ulong(strnum,(unsigned long) u)] = 0;
  cookie(hash,key.s,key.len,strnum,line.s,"-e");
  if (str_len(x) != COOKIE) die_cookie();
  if (byte_diff(hash,COOKIE,x)) die_cookie();
	/* cookie is ok, file exists, lock's on, new file ends in '_' */
  stralloc_copys(&fneditn,fnedit.s);
  stralloc_append(&fneditn,'_');
  stralloc_0(&fneditn);
  fd = open_trunc(fneditn.s);
  if (fd == -1)
    strerr_die2sys(111,FATAL,MSG1(ERR_WRITE,fneditn.s));
  substdio_fdbuf(&sstext,write,fd,textbuf,sizeof(textbuf));
  stralloc_copys(&quoted,"");	/* clear */
  stralloc_copys(&text,"");

  for (;;) {			/* get message body */
    if (getln(&ssin,&line,&match,'\n') == -1)
      strerr_die2sys(111,FATAL,MSG(ERR_READ_INPUT));
    if (!match) break;
    stralloc_cat(&text,&line);
  }
  if (encin) {			/* decode if necessary */
    if (encin == 'B')
      decodeB(text.s,text.len,&line);
    else
      decodeQ(text.s,text.len,&line);
    stralloc_copy(&text,&line);
  }
  cp = text.s;
  cpafter = text.s+text.len;
  flaggoodfield = 0;
  flagdone = 0;
  len = 0;
  while ((cpnext = cp + byte_chr(cp,cpafter-cp,'\n')) != cpafter) {
    i = byte_chr(cp,cpnext-cp,'%');
    if (i != (unsigned int) (cpnext - cp)) {
      if (!flaggoodfield) {	/* MSG(TXT_EDIT_START)/END */
	if (case_startb(cp+i,cpnext-cp-i,MSG(TXT_EDIT_START))) {
		/* start tag. Store users 'quote characters', e.g. '> ' */
	  stralloc_copyb(&quoted,cp,i);
	  flaggoodfield = 1;
	  cp = cpnext + 1;
	  continue;
	}
      } else
	if (case_startb(cp+i,cpnext-cp-i,MSG(TXT_EDIT_END))) {
	  flagdone = 1;
	  break;
	}
    }
    if (flaggoodfield) {
      if ((len += cpnext - cp - quoted.len + 1) > MAXEDIT)
	strerr_die1x(100,MSG(ERR_EDSIZE));

      if (quoted.len && cpnext-cp >= (int) quoted.len &&
	  !str_diffn(cp,quoted.s,quoted.len))
	cp += quoted.len;	/* skip quoting characters */
      cplast = cpnext - 1;
      if (*cplast == '\r')	/* CRLF -> '\n' for base64 encoding */
	*cplast = '\n';
      else
	++cplast;
      if (substdio_put(&sstext,cp,cplast-cp+1) == -1)
	strerr_die2sys(111,FATAL,MSG1(ERR_WRITE,fneditn.s));
    }
    cp = cpnext + 1;
  }
  if (!flagdone)
    strerr_die2x(100,FATAL,MSG(ERR_NO_MARK));
  if (substdio_flush(&sstext) == -1)
    strerr_die2sys(111,FATAL,MSG1(ERR_WRITE,fneditn.s));
  if (fsync(fd) == -1)
    strerr_die2sys(111,FATAL,MSG1(ERR_SYNC,fneditn.s));
  if (fchmod(fd, 0600) == -1)
    strerr_die2sys(111,FATAL,MSG1(ERR_CHMOD,fneditn.s));
  if (close(fd) == -1)
    strerr_die2sys(111,FATAL,MSG1(ERR_CLOSE,fneditn.s));
  wrap_rename(fneditn.s,fnedit.s);

  unlock();
  hdr_subject(MSG1(SUB_EDIT_SUCCESS,fname));
  hdr_ctboundary();
  copy(&qq,"text/top",flagcd);
  copy_act("text/edit-done");
  copybottom(0);
  qmail_to(&qq,sender);		/* not necessarily from mod */
}
예제 #20
0
int main(int argc,char **argv)
{
  int child;
  const char *sendargs[4];
  stralloc addr = {0};
  unsigned int pos = 0,pos2,poslocal,len;
  const char *cp;

  unsigned long hh = 4L;		/* default time 04:12 */
  unsigned long mm = 12L;
  const char *dow = "*";		/* day of week */
  const char *qmail_inject = "/bin/qmail-inject ";
  char strnum[FMT_ULONG];
  unsigned long uid,euid = 0;

  stralloc rp = {0};
  stralloc user = {0};
  stralloc euser = {0};
  stralloc dir = {0};
  stralloc listaddr = {0};
  stralloc line = {0};

  struct passwd *ppasswd;

  int match;
  int hostmatch;
  int localmatch;
  unsigned long dh,t;
  int founduser = 0;
  int listmatch = 0;
  int flagdigit = 0;
  int flagours;
  int foundlocal = 0;
  int foundmatch = 0;
  unsigned int nolists = 0;
  unsigned long maxlists;
  unsigned int lenhost,lenlocal;
  int fdin,fdout = -1;

  char *local = (char *) 0;	/* list = local@host */
  const char *host = (char *) 0;
  char *code = (char *) 0;	/* digest code */

  char inbuf[512];
  substdio ssin;

  char outbuf[512];
  substdio ssout;

  (void) umask(077);
  sig_pipeignore();

  optind = getconfopt(argc,argv,options,0,0);
  if (flagt != 0) {
    pos = scan_ulong(flagt,&hh);
    if (flagt[pos++] != ':') die_usage();
    (void) scan_ulong(flagt + pos,&mm);
  }
  if (flagw != 0) {
    dow = flagw;
    cp = flagw - 1;
    while (*(++cp)) {
      if (*cp >= '0' && *cp <= '7') {
	if (flagdigit) die_dow();
	flagdigit = 1;
      } else if (*cp == ',') {
	if (!flagdigit) die_dow();
	flagdigit = 0;
      } else
	die_dow();
    }
  }

  if (flaglist + flagdelete + flagconfig > 1)
    strerr_die2x(100,FATAL,MSG(ERR_EXCLUSIVE));
  uid = getuid();
  if (uid && !(euid = geteuid()))
    strerr_die2x(100,FATAL,MSG(ERR_SUID));
  if (!(ppasswd = getpwuid(uid)))
    strerr_die2x(100,FATAL,MSG(ERR_UID));
  if (!stralloc_copys(&user,ppasswd->pw_name)) die_nomem();
  if (!stralloc_0(&user)) die_nomem();
  if (!(ppasswd = getpwuid(euid)))
    strerr_die2x(100,FATAL,MSG(ERR_EUID));
  if (!stralloc_copys(&dir,ppasswd->pw_dir)) die_nomem();
  if (!stralloc_0(&dir)) die_nomem();
  if (!stralloc_copys(&euser,ppasswd->pw_name)) die_nomem();
  if (!stralloc_0(&euser)) die_nomem();

  wrap_chdir(dir.s);

  local = argv[optind++];	/* list address, optional for -c & -l */
  if (!local) {
    if (!flagconfig && !flaglist)
      die_usage();
    lenlocal = 0;
    lenhost = 0;
  } else {
    if (!stralloc_copys(&listaddr,local)) die_nomem();
    if (!isclean(local,1))
      die_argument();
    pos = str_chr(local,'@');
    lenlocal = pos;
    local[pos] = '\0';
    host = local + pos + 1;
    lenhost = str_len(host);
    code = argv[optind];
    if (!code) {		/* ignored for -l, -c, and -d */
      if (flagdelete || flaglist || flagconfig)
				/* get away with not putting code for delete */
        code = (char*)"a";	/* a hack - so what! */
      else
        die_usage();
    } else
      if (!isclean(code,0))
        die_argument();
  }
  if ((fdin = open_read(TXT_EZCRONRC)) == -1)
    strerr_die2sys(111,FATAL,MSG1(ERR_OPEN,TXT_EZCRONRC));
	/* first line is special */
  substdio_fdbuf(&ssin,read,fdin,inbuf,sizeof(inbuf));
  if (getln(&ssin,&line,&match,'\n') == -1)
    strerr_die2sys(111,FATAL,MSG1(ERR_READ,TXT_EZCRONRC));

  if (!match)
    strerr_die2sys(111,FATAL,MSG1(ERR_READ,TXT_EZCRONRC));
	/* (since we have match line.len has to be >= 1) */
  line.s[line.len - 1] = '\0';
  if (!isclean(line.s,0))	 /* host for bounces */
    strerr_die2x(100,FATAL,MSG1(ERR_CFHOST,TXT_EZCRONRC));
  if (!stralloc_copys(&rp,line.s)) die_nomem();

  match = 1;
  for(;;) {
    if (!match) break;		/* to allow last line without '\n' */
    if (getln(&ssin,&line,&match,'\n') == -1)
    strerr_die2sys(111,FATAL,MSG1(ERR_READ,TXT_EZCRONRC));
    if (!line.len)
      break;
    line.s[line.len-1] = '\0';
    if (!case_startb(line.s,line.len,user.s))
      continue;
    pos = user.len - 1;
    if (pos >= line.len || line.s[pos] != ':')
      continue;
    founduser = 1;		 /* got user line */
    break;
  }
  close(fdin);
  if (!founduser)
    strerr_die2x(100,FATAL,MSG(ERR_BADUSER));
  
  if (flagconfig) {
    line.s[line.len-1] = '\n';	/* not very elegant ;-) */
    substdio_fdbuf(&ssout,write,1,outbuf,sizeof(outbuf));
    if (substdio_put(&ssout,line.s,line.len) == -1)
      strerr_die2sys(111,FATAL,MSG(ERR_WRITE_STDOUT));
    if (substdio_flush(&ssout) == -1)
      strerr_die2sys(111,FATAL,MSG(ERR_WRITE_STDOUT));
    _exit(0);
  }
  ++pos;				/* points to first ':' */
  len = str_chr(line.s+pos,':');	/* second ':' */
    if (!line.s[pos + len])
      die_syntax(&line);
  if (!local) {				/* only -d and std left */
    localmatch = 1;
    hostmatch = 1;
  } else {
    hostmatch = 0;
    if (len <= str_len(local))
      if (!str_diffn(line.s+pos,local,len))
        localmatch = 1;
  }
  pos += len + 1;
  len = str_chr(line.s + pos,':');	/* third */
  if (!line.s[pos + len])
    die_syntax(&line);
  if (local) {				/* check host */
    if (len == 0)			/* empty host => any host */
      hostmatch = 1;
    else
      if (len == str_len(host))
        if (!case_diffb(line.s+pos,len,host))
          hostmatch = 1;
  }
  pos += len + 1;
  pos += scan_ulong(line.s+pos,&maxlists);
  if (line.s[pos]) {			/* check additional lists */
    if (line.s[pos] != ':')
      die_syntax(&line);
    if (line.s[pos+1+str_chr(line.s+pos+1,':')])
      die_syntax(&line);	/* reminder lists are not separated by ':'  */
				/* otherwise a ':' or arg miscount will die */
				/* silently */
    if (local) {
      while (++pos < line.len) {
        len = str_chr(line.s + pos,'@');
        if (len == lenlocal && !str_diffn(line.s + pos,local,len)) {
          pos += len;
          if (!line.s[pos]) break;
          pos++;
          len = str_chr(line.s+pos,',');
            if (len == lenhost && !case_diffb(line.s+pos,len,host)) {
              listmatch = 1;
              break;
            }
        }
        pos += len;
      }
    }
  }
  if (!listmatch) {
    if (!hostmatch)
      strerr_die2x(100,FATAL,MSG(ERR_BADHOST));
    if (!localmatch)
      strerr_die2x(100,FATAL,MSG(ERR_BADLOCAL));
  }
	/* assemble correct line */
  if (!flaglist) {
    if (!stralloc_copyb(&addr,strnum,fmt_ulong(strnum,mm))) die_nomem();
    if (!stralloc_cats(&addr," ")) die_nomem();
    dh = 0L;
    if (deltah <= 3L) dh = deltah;
    else if (deltah <= 6L) dh = 6L;
    else if (deltah <= 12L) dh = 12L;
    else if (deltah <= 24L) dh = 24L;
    else if (deltah <= 48L) {
      if (dow[0] == '*') dow = "1,3,5";
    } else if (deltah <= 72L) {
      if (dow[0] == '*') dow = "1,4";
    } else
    if (dow[0] == '*') dow = "1";

    if (!dh) {
      if (!stralloc_cats(&addr,"*")) die_nomem();
    } else {
      if (!stralloc_catb(&addr,strnum,fmt_ulong(strnum,hh))) die_nomem();
      for (t = hh + dh; t < hh + 24L; t+=dh) {
        if (!stralloc_cats(&addr,",")) die_nomem();
        if (!stralloc_catb(&addr,strnum,fmt_ulong(strnum,t % 24L))) die_nomem();
      }
    }
    if (!stralloc_cats(&addr," * * ")) die_nomem();
    if (!stralloc_cats(&addr,dow)) die_nomem();
    if (!stralloc_cats(&addr," ")) die_nomem();
    if (!stralloc_cats(&addr,auto_qmail)) die_nomem();
    if (!stralloc_cats(&addr,qmail_inject)) die_nomem();
    if (!stralloc_cats(&addr,local)) die_nomem();
    if (!stralloc_cats(&addr,"-dig-")) die_nomem();
    if (!stralloc_cats(&addr,code)) die_nomem();
    if (!stralloc_cats(&addr,"@")) die_nomem();
    if (!stralloc_cats(&addr,host)) die_nomem();
		/* feed 'Return-Path: <user@host>' to qmail-inject */
    if (!stralloc_cats(&addr,"%Return-path: <")) die_nomem();
    if (!stralloc_cats(&addr,user.s)) die_nomem();
    if (!stralloc_cats(&addr,"@")) die_nomem();
    if (!stralloc_cat(&addr,&rp)) die_nomem();
    if (!stralloc_cats(&addr,">\n")) die_nomem();
  }
  if (!stralloc_0(&addr)) die_nomem();

  if (!flaglist) {
	/* now to rewrite crontab we need to lock */
    lockfile("crontabl");
  } /* if !flaglist */
  if ((fdin = open_read("crontab")) == -1) {
    if (errno != error_noent)
      strerr_die2sys(111,FATAL,MSG1(ERR_READ,"crontab"));
  } else
    substdio_fdbuf(&ssin,read,fdin,inbuf,sizeof(inbuf));
  if (flaglist)
    substdio_fdbuf(&ssout,write,1,outbuf,sizeof(outbuf));
  else {
    if ((fdout = open_trunc("crontabn")) == -1)
      strerr_die2sys(111,FATAL,MSG1(ERR_WRITE,"crontabn"));
    substdio_fdbuf(&ssout,write,fdout,outbuf,sizeof(outbuf));
  }
  line.len = 0;

  if (fdin != -1) {
    for (;;) {
      if (!flaglist && line.len) {
        line.s[line.len-1] = '\n';
        if (substdio_put(&ssout,line.s,line.len) == -1)
          strerr_die2sys(111,FATAL,MSG1(ERR_WRITE,"crontabn"));
      }
      if (getln(&ssin,&line,&match,'\n') == -1)
        strerr_die2sys(111,FATAL,MSG1(ERR_READ,"crontab"));
      if (!match)
        break;
      flagours = 0;			/* assume entry is not ours */
      foundlocal = 0;
      line.s[line.len - 1] = '\0';	/* match so at least 1 char */
      pos = 0;
      while (line.s[pos] == ' ' || line.s[pos] == '\t') ++pos;
      if (line.s[pos] == '#')
        continue;			/* cron comment */
      pos = str_chr(line.s,'/');
      if (!str_start(line.s+pos,auto_qmail)) continue;
      pos += str_len(auto_qmail);
      if (!str_start(line.s+pos,qmail_inject)) continue;
      pos += str_len(qmail_inject);
      poslocal = pos;
      pos = byte_rchr(line.s,line.len,'<');	/* should be Return-Path: < */
      if (pos == line.len)
        continue;			/* not ezmlm-cron line */
      pos++;
     len = str_chr(line.s+pos,'@');
      if (len == user.len - 1 && !str_diffn(line.s+pos,user.s,len)) {
        flagours = 1;
        ++nolists;		/* belongs to this user */
      }
      if (!local) {
        foundlocal = 1;
      } else {
        pos = poslocal + str_chr(line.s+poslocal,'@');
        if (pos + lenhost +1 >= line.len) continue;
        if (case_diffb(line.s+pos+1,lenhost,host)) continue;
        if (line.s[pos+lenhost+1] != '%') continue;
				/* check local */
        if (poslocal + lenlocal + 5 >= line.len) continue;
        if (!str_start(line.s+poslocal,local)) continue;
        pos2 = poslocal+lenlocal;
        if (!str_start(line.s+pos2,"-dig-")) continue;
        foundlocal = 1;
      }
      if (foundlocal) {
        foundmatch = 1;
        if (flaglist && (local || flagours)) {
          if (substdio_put(&ssout,line.s,line.len) == -1)
            strerr_die2sys(111,FATAL,MSG(ERR_WRITE_STDOUT));
          if (substdio_put(&ssout,"\n",1) == -1)
            strerr_die2sys(111,FATAL,MSG(ERR_WRITE_STDOUT));
        }
        line.len = 0;		/* same - kill line */
        if (flagours)
          --nolists;
      }
    }
    close(fdin);
  }
  if (flaglist) {
    if (substdio_flush(&ssout) == -1)
      strerr_die2sys(111,FATAL,MSG1(ERR_FLUSH,"stdout"));
    if (foundmatch)		/* means we had a match */
      _exit(0);
    else
      strerr_die2x(100,FATAL,MSG(ERR_NO_MATCH));
  }
	/* only -d and regular use left */

  if (nolists >= maxlists && !flagdelete)
    strerr_die2x(100,FATAL,MSG(ERR_LISTNO));
  if (!flagdelete)
    if (substdio_put(&ssout,addr.s,addr.len-1) == -1)
      strerr_die2sys(111,FATAL,MSG1(ERR_WRITE,"crontabn"));
  if (flagdelete && !foundlocal)
    strerr_die2x(111,FATAL,MSG(ERR_NO_MATCH));
  if (substdio_flush(&ssout) == -1)
    strerr_die2sys(111,FATAL,MSG1(ERR_FLUSH,"crontabn"));
  if (fsync(fdout) == -1)
    strerr_die2sys(111,FATAL,MSG1(ERR_SYNC,"crontabn++"));
  if (close(fdout) == -1)
    strerr_die2sys(111,FATAL,MSG1(ERR_CLOSE,"crontabn"));
  wrap_rename("crontabn","crontab");
  sendargs[0] = "sh";
  sendargs[1] = "-c";

  if (!stralloc_copys(&line,auto_cron)) die_nomem();
  if (!stralloc_cats(&line,"/crontab '")) die_nomem();
  if (!stralloc_cats(&line,dir.s)) die_nomem();
  if (!stralloc_cats(&line,"/crontab'")) die_nomem();
  if (!stralloc_0(&line)) die_nomem();
  sendargs[2] = line.s;
  sendargs[3] = 0;
  if ((child = wrap_fork()) == 0) {
    if (setreuid(euid,euid) == -1)
      strerr_die2sys(100,FATAL,MSG(ERR_SETUID));
    wrap_execvp(sendargs);
  }
  /* parent */
  switch (wrap_waitpid(child)) {
      case 0:
        _exit(0);
      default:
        strerr_die2x(111,FATAL,MSG(ERR_CRONTAB));
  }
}
예제 #21
0
int
main(int argc, char *argv[])
{
    int fddata = 0;
    unsigned int i = 0, j = 0, k = 0;

    unsigned long u = 0;
    unsigned long ttl = 0;

    char ch = 0;
    char *x = NULL;
    char ttd[8], loc[2];
    char ip[4], type[2];
    char soa[20], buf[4];

    prog = strdup ((x = strrchr (argv[0], '/')) != NULL ? x + 1 : argv[0]);
    i = check_option (argc, argv);
    argv += i;
    argc -= i;

    umask(022);

    if ((fddata = open_read ("data")) == -1)
        err (-1, "could not open file `data'");
    defaultsoa_init (fddata);

    buffer_init (&b, buffer_unixread, fddata, bspace, sizeof bspace);

    if ((fdcdb = open_trunc ("data.tmp")) == -1)
        err (-1, "could not create file `data.tmp'");
    if (cdb_make_start (&cdb, fdcdb) == -1)
        err (-1, "could not create file `data.tmp'");

    while (match)
    {
        linenum++;
        if (getln (&b, &line, &match, '\n') == -1)
            err (-1, "could not read line: %ld", linenum);

        while (line.len)
        {
            ch = line.s[line.len - 1];
            if ((ch != ' ') && (ch != '\t') && (ch != '\n'))
                break;

            --line.len;
        }
        if (!line.len)
            continue;
        if (line.s[0] == '#')
            continue;
        if (line.s[0] == '-')
            continue;

        j = 1;
        for (i = 0; i < NUMFIELDS; i++)
        {
            if (j >= line.len)
            {
                if (!stralloc_copys (&f[i], ""))
                    err (-1, "could not allocate enough memory");
            }
            else
            {
                k = byte_chr (line.s + j, line.len - j, ':');
                if (!stralloc_copyb (&f[i], line.s + j, k))
                    err (-1, "could not allocate enough memory");
                j += k + 1;
            }
        }

        switch (line.s[0])
        {
        case '%':
            locparse (&f[0], loc);

            if (!stralloc_copyb (&key, "\0%", 2))
                err (-1, "could not allocate enough memory");
            if (!stralloc_0 (&f[1]))
                err (-1, "could not allocate enough memory");

            ipprefix_cat (&key, f[1].s);

            if (cdb_make_add(&cdb,key.s,key.len,loc,2) == -1)
                err (-1, "could not create file `data.tmp'");

            break;

        case 'Z':
            if (!dns_domain_fromdot (&d1, f[0].s, f[0].len))
                err (-1, "could not allocate enough memory");

            if (!stralloc_0 (&f[3]))
                err (-1, "could not allocate enough memory");
            if (!scan_ulong (f[3].s, &u))
                uint32_unpack_big (defaultsoa, (uint32 *)&u);
            uint32_pack_big (soa, u);

            if (!stralloc_0 (&f[4]))
                err (-1, "could not allocate enough memory");
            if (!scan_ulong (f[4].s, &u))
                uint32_unpack_big (defaultsoa + 4, (uint32 *)&u);
            uint32_pack_big (soa + 4, u);

            if (!stralloc_0 (&f[5]))
                err (-1, "could not allocate enough memory");
            if (!scan_ulong (f[5].s, &u))
                uint32_unpack_big (defaultsoa + 8, (uint32 *)&u);
            uint32_pack_big (soa + 8, u);

            if (!stralloc_0 (&f[6]))
                err (-1, "could not allocate enough memory");
            if (!scan_ulong (f[6].s, &u))
                uint32_unpack_big (defaultsoa + 12, (uint32 *)&u);
            uint32_pack_big (soa + 12, u);

            if (!stralloc_0 (&f[7]))
                err (-1, "could not allocate enough memory");
            if (!scan_ulong (f[7].s, &u))
                uint32_unpack_big (defaultsoa + 16, (uint32 *)&u);
            uint32_pack_big (soa + 16, u);

            if (!stralloc_0 (&f[8]))
                err (-1, "could not allocate enough memory");
            if (!scan_ulong(f[8].s,&ttl))
                ttl = TTL_NEGATIVE;

            ttdparse (&f[9], ttd);
            locparse (&f[10], loc);

            rr_start (DNS_T_SOA, ttl, ttd, loc);
            if (!dns_domain_fromdot (&d2, f[1].s, f[1].len))
                err (-1, "could not allocate enough memory");

            rr_addname (d2);
            if (!dns_domain_fromdot (&d2, f[2].s, f[2].len))
                err (-1, "could not allocate enough memory");

            rr_addname (d2);
            rr_add (soa, 20);
            rr_finish (d1);

            break;

        case '.':
        case '&':
            if (!dns_domain_fromdot (&d1, f[0].s, f[0].len))
                err (-1, "could not allocate enough memory");
            if (!stralloc_0 (&f[3]))
                err (-1, "could not allocate enough memory");
            if (!scan_ulong (f[3].s, &ttl))
                ttl = TTL_NS;

            ttdparse (&f[4], ttd);
            locparse (&f[5], loc);

            if (!stralloc_0 (&f[1]))
                err (-1, "could not allocate enough memory");

            if (byte_chr (f[2].s, f[2].len, '.') >= f[2].len)
            {
                if (!stralloc_cats (&f[2], ".ns."))
                    err (-1, "could not allocate enough memory");
                if (!stralloc_catb (&f[2], f[0].s, f[0].len))
                    err (-1, "could not allocate enough memory");
            }
            if (!dns_domain_fromdot (&d2, f[2].s, f[2].len))
                err (-1, "could not allocate enough memory");

            if (line.s[0] == '.')
            {
                rr_start (DNS_T_SOA, ttl ? TTL_NEGATIVE : 0, ttd, loc);
                rr_addname (d2);

                rr_add ("\12hostmaster", 11);
                rr_addname (d1);

                rr_add (defaultsoa, 20);
                rr_finish (d1);
            }

            rr_start (DNS_T_NS, ttl, ttd, loc);
            rr_addname (d2);
            rr_finish (d1);

            if (ip4_scan (f[1].s, ip))
            {
                rr_start (DNS_T_A, ttl, ttd, loc);
                rr_add (ip, 4);
                rr_finish (d2);
            }

            break;

        case '+':
        case '=':
            if (!dns_domain_fromdot (&d1, f[0].s, f[0].len))
                err (-1, "could not allocate enough memory");
            if (!stralloc_0 (&f[2]))
                err (-1, "could not allocate enough memory");

            if (!scan_ulong (f[2].s, &ttl))
                ttl = TTL_POSITIVE;

            ttdparse (&f[3], ttd);
            locparse (&f[4], loc);

            if (!stralloc_0 (&f[1]))
                err (-1, "could not allocate enough memory");

            if (ip4_scan (f[1].s, ip))
            {
                rr_start (DNS_T_A, ttl, ttd, loc);
                rr_add (ip, 4);
                rr_finish (d1);

                if (line.s[0] == '=')
                {
                    dns_name4_domain (dptr,ip);
                    rr_start (DNS_T_PTR, ttl, ttd, loc);
                    rr_addname (d1);
                    rr_finish (dptr);
                }
            }
            break;

        case '@':
            if (!dns_domain_fromdot (&d1, f[0].s, f[0].len))
                err (-1, "could not allocate enough memory");
            if (!stralloc_0 (&f[4]))
                err (-1, "could not allocate enough memory");
            if (!scan_ulong (f[4].s, &ttl))
                ttl = TTL_POSITIVE;

            ttdparse (&f[5], ttd);
            locparse (&f[6], loc);

            if (!stralloc_0 (&f[1]))
                err (-1, "could not allocate enough memory");

            if (byte_chr (f[2].s, f[2].len, '.') >= f[2].len)
            {
                if (!stralloc_cats (&f[2], ".mx."))
                    err (-1, "could not allocate enough memory");
                if (!stralloc_catb (&f[2], f[0].s, f[0].len))
                    err (-1, "could not allocate enough memory");
            }
            if (!dns_domain_fromdot (&d2, f[2].s, f[2].len))
                err (-1, "could not allocate enough memory");

            if (!stralloc_0 (&f[3]))
                err (-1, "could not allocate enough memory");
            if (!scan_ulong (f[3].s, &u))
                u = 0;

            rr_start (DNS_T_MX, ttl, ttd, loc);
            uint16_pack_big (buf, u);
            rr_add (buf, 2);
            rr_addname (d2);
            rr_finish (d1);

            if (ip4_scan (f[1].s, ip))
            {
                rr_start (DNS_T_A, ttl, ttd, loc);
                rr_add (ip, 4);
                rr_finish (d2);
            }
            break;

        case '^':
        case 'C':
            if (!dns_domain_fromdot (&d1, f[0].s, f[0].len))
                err (-1, "could not allocate enough memory");
            if (!dns_domain_fromdot (&d2, f[1].s, f[1].len))
                err (-1, "could not allocate enough memory");
            if (!stralloc_0 (&f[2]))
                err (-1, "could not allocate enough memory");
            if (!scan_ulong (f[2].s, &ttl))
                ttl = TTL_POSITIVE;

            ttdparse (&f[3], ttd);
            locparse (&f[4], loc);

            if (line.s[0] == 'C')
                rr_start (DNS_T_CNAME, ttl, ttd, loc);
            else
                rr_start (DNS_T_PTR, ttl, ttd, loc);

            rr_addname (d2);
            rr_finish (d1);

            break;

        case '\'':
            if (!dns_domain_fromdot (&d1, f[0].s, f[0].len))
                err (-1, "could not allocate enough memory");
            if (!stralloc_0 (&f[2]))
                err (-1, "could not allocate enough memory");
            if (!scan_ulong (f[2].s, &ttl))
                ttl = TTL_POSITIVE;

            ttdparse (&f[3], ttd);
            locparse (&f[4], loc);

            rr_start (DNS_T_TXT, ttl, ttd, loc);

            txtparse (&f[1]);
            i = 0;
            while (i < f[1].len)
            {
                k = f[1].len - i;
                if (k > 127)
                    k = 127;
                ch = k;
                rr_add (&ch, 1);
                rr_add (f[1].s + i, k);
                i += k;
            }

            rr_finish (d1);
            break;

        case ':':
            if (!dns_domain_fromdot (&d1, f[0].s, f[0].len))
                err (-1, "could not allocate enough memory");
            if (!stralloc_0 (&f[3]))
                err (-1, "could not allocate enough memory");
            if (!scan_ulong (f[3].s, &ttl))
                ttl = TTL_POSITIVE;

            ttdparse (&f[4], ttd);
            locparse (&f[5], loc);

            if (!stralloc_0 (&f[1]))
                err (-1, "could not allocate enough memory");
            scan_ulong (f[1].s, &u);
            uint16_pack_big (type, u);
            if (byte_equal (type, 2, DNS_T_AXFR))
                syntaxerror (": type AXFR prohibited");
            if (byte_equal (type, 2, "\0\0"))
              syntaxerror (": type 0 prohibited");
            if (byte_equal (type, 2, DNS_T_SOA))
              syntaxerror (": type SOA prohibited");
            if (byte_equal (type, 2, DNS_T_NS))
              syntaxerror (": type NS prohibited");
            if (byte_equal (type, 2, DNS_T_CNAME))
              syntaxerror (": type CNAME prohibited");
            if (byte_equal (type, 2, DNS_T_PTR))
              syntaxerror (": type PTR prohibited");
            if (byte_equal (type, 2, DNS_T_MX))
              syntaxerror (": type MX prohibited");

            txtparse (&f[2]);

            rr_start (type, ttl, ttd, loc);
            rr_add (f[2].s, f[2].len);
            rr_finish (d1);

            break;

        default:
            syntaxerror (": unrecognized leading character");
        }
    }

    if (cdb_make_finish (&cdb) == -1)
        err (-1, "could not create file `data.tmp'");
    if (fsync (fdcdb) == -1)
        err (-1, "could not create file `data.tmp'");
    if (close (fdcdb) == -1)
        err (-1, "could not create file `data.tmp'"); /* NFS stupidity */
    if (rename ("data.tmp", "data.cdb") == -1)
        err (-1, "could not move `data.tmp' to `data.cdb'");

    return 0;
}
예제 #22
0
int std_subscribe(const char *dir,
		  const char *subdir,
		  const char *userhost,
		  int flagadd,
		  const char *comment,
		  const char *event,
		  int forcehash)
/* add (flagadd=1) or remove (flagadd=0) userhost from the subscr. database  */
/* dbname. Comment is e.g. the subscriber from line or name. It is added to  */
/* the log. Event is the action type, e.g. "probe", "manual", etc. The       */
/* direction (sub/unsub) is inferred from flagadd. Returns 1 on success, 0   */
/* on failure. If flagmysql is set and the file "sql" is found in the        */
/* directory dbname, it is parsed and a mysql db is assumed. if forcehash is */
/* >=0 it is used in place of the calculated hash. This makes it possible to */
/* add addresses with a hash that does not exist. forcehash has to be 0..99. */
/* for unsubscribes, the address is only removed if forcehash matches the    */
/* actual hash. This way, ezmlm-manage can be prevented from touching certain*/
/* addresses that can only be removed by ezmlm-unsub. Usually, this would be */
/* used for sublist addresses (to avoid removal) and sublist aliases (to     */
/* prevent users from subscribing them (although the cookie mechanism would  */
/* prevent the resulting duplicate message from being distributed. */
{
  int fdlock;

  unsigned int j;
  unsigned char ch,lcch;
  int match;
  int flagwasthere;

  if (userhost[str_chr(userhost,'\n')])
    strerr_die2x(100,FATAL,ERR_ADDR_NL);

    if (!stralloc_copys(&addr,"T")) die_nomem();
    if (!stralloc_cats(&addr,userhost)) die_nomem();
    if (addr.len > 401)
      strerr_die2x(100,FATAL,ERR_ADDR_LONG);

    j = byte_rchr(addr.s,addr.len,'@');
    if (j == addr.len)
      strerr_die2x(100,FATAL,ERR_ADDR_AT);
    case_lowerb(addr.s + j + 1,addr.len - j - 1);
    if (!stralloc_copy(&lcaddr,&addr)) die_nomem();
    case_lowerb(lcaddr.s + 1,j - 1);	/* make all-lc version of address */

    if (forcehash >= 0 && forcehash <= 52) {
      ch = lcch = 64 + (unsigned char) forcehash;
    } else {
      ch = 64 + subhashsa(&addr);
      lcch = 64 + subhashsa(&lcaddr);
    }

    if (!stralloc_0(&addr)) die_nomem();
    if (!stralloc_0(&lcaddr)) die_nomem();
    std_makepath(&fn,dir,subdir,"/subscribers/",lcch);
    std_makepath(&fnlock,dir,subdir,"/lock",0);

    if (!stralloc_copyb(&fnnew,fn.s,fn.len-1)) die_nomem();
	/* code later depends on fnnew = fn + 'n' */
    if (!stralloc_cats(&fnnew,"n")) die_nomem();
    if (!stralloc_0(&fnnew)) die_nomem();

    fdlock = lockfile(fnlock.s);

				/* do lower case hashed version first */
    fdnew = open_trunc(fnnew.s);
    if (fdnew == -1) die_write();
    substdio_fdbuf(&ssnew,write,fdnew,ssnewbuf,sizeof(ssnewbuf));

    flagwasthere = 0;

    fd = open_read(fn.s);
    if (fd == -1) {
      if (errno != error_noent) { close(fdnew); die_read(); }
    }
    else {
      substdio_fdbuf(&ss,read,fd,ssbuf,sizeof(ssbuf));

      for (;;) {
        if (getln(&ss,&line,&match,'\0') == -1) {
	  close(fd); close(fdnew); die_read();
        }
        if (!match) break;
        if (line.len == addr.len)
          if (!case_diffb(line.s,line.len,addr.s)) {
	    flagwasthere = 1;
	    if (!flagadd)
	      continue;
	  }
        if (substdio_bput(&ssnew,line.s,line.len) == -1) {
	  close(fd); close(fdnew); die_write();
        }
      }

      close(fd);
    }

    if (flagadd && !flagwasthere)
      if (substdio_bput(&ssnew,addr.s,addr.len) == -1) {
        close(fdnew); die_write();
      }

    if (substdio_flush(&ssnew) == -1) { close(fdnew); die_write(); }
    if (fsync(fdnew) == -1) { close(fdnew); die_write(); }
    close(fdnew);

    if (rename(fnnew.s,fn.s) == -1)
      strerr_die6sys(111,FATAL,ERR_MOVE,fnnew.s," to ",fn.s,": ");

    if ((ch == lcch) || flagwasthere) {
      close(fdlock);
      if (flagadd ^ flagwasthere) {
        if (!stralloc_0(&addr)) die_nomem();
        logaddr(dir,subdir,event,addr.s+1,comment);
        return 1;
      }
      return 0;
    }

			/* If unsub and not found and hashed differ, OR */
			/* sub and not found (so added with new hash) */
			/* do the 'case-dependent' hash */

    fn.s[fn.len - 2] = ch;
    fnnew.s[fnnew.len - 3] = ch;
    fdnew = open_trunc(fnnew.s);
    if (fdnew == -1) die_write();
    substdio_fdbuf(&ssnew,write,fdnew,ssnewbuf,sizeof(ssnewbuf));

    fd = open_read(fn.s);
    if (fd == -1) {
      if (errno != error_noent) { close(fdnew); die_read(); }
    } else {
      substdio_fdbuf(&ss,read,fd,ssbuf,sizeof(ssbuf));

      for (;;) {
        if (getln(&ss,&line,&match,'\0') == -1)
          { close(fd); close(fdnew); die_read(); }
        if (!match) break;
        if (line.len == addr.len)
          if (!case_diffb(line.s,line.len,addr.s)) {
            flagwasthere = 1;
            continue;	/* always want to remove from case-sensitive hash */
          }
        if (substdio_bput(&ssnew,line.s,line.len) == -1)
          { close(fd); close(fdnew); die_write(); }
      }

      close(fd);
    }

    if (substdio_flush(&ssnew) == -1) { close(fdnew); die_write(); }
    if (fsync(fdnew) == -1) { close(fdnew); die_write(); }
    close(fdnew);

    if (rename(fnnew.s,fn.s) == -1)
      strerr_die6sys(111,FATAL,ERR_MOVE,fnnew.s," to ",fn.s,": ");

    close(fdlock);
    if (flagadd ^ flagwasthere) {
      if (!stralloc_0(&addr)) die_nomem();
      logaddr(dir,subdir,event,addr.s+1,comment);
      return 1;
    }
    return 0;

}
예제 #23
0
파일: vdnsdb.c 프로젝트: malfaux/geoipdns
int main(int argc, char **argv)
{
  int fddata;
	uint32 loc;
	//int v;
	char ipa[4];
	//char ipb[4];
	//ip4_cidr_t *subnets = (ip4_cidr_t *)NULL;
	//unsigned int slen = 0;
	uint32 ipinta = 0U;
	//unsigned int ipintb = 0;
	unsigned short mask;
	uint32 uid = 0;
	uint32  mid = 0;
  int i;
  int j;
  int k;
  char ch;
  unsigned long ttl;
  char ttd[8];
  //uint32 loc;
	unsigned char keyloc[15];
  unsigned long u;
  char ip[4];
	char locp[4];
	//char map[9];
  char type[2];
  char soa[20];
  char buf[4];
  //int namlen = 0;
  umask(022);
  fddata = STDIN_FILENO;
	if (argc != 3) {
    fddata = open_read("data");
		if (fddata == -1) strerr_die2sys(111,FATAL,"unable to open data: ");
		if ( (fdcdb = open_trunc("data.tmp")) == -1) die_datatmp();
	} else {
		fddata = STDIN_FILENO;
		if ( (fdcdb = open_trunc(argv[1])) == -1) die_datatmp();
	}
	
  defaultsoa_init(fddata);

  buffer_init(&b,buffer_unixread,fddata,bspace,sizeof bspace);

  if (cdb_make_start(&cdb,fdcdb) == -1) die_datatmp();

  while (match) {
    ++linenum;
    if (getln(&b,&line,&match,'\n') == -1)
      strerr_die2sys(111,FATAL,"unable to read line: ");

    while (line.len) {
      ch = line.s[line.len - 1];
      if ((ch != ' ') && (ch != '\t') && (ch != '\n')) break;
      --line.len;
    }
    if (!line.len) continue;
    if (line.s[0] == '#') continue;
    if (line.s[0] == '-') continue;
		//write(1,line.s,line.len);
		//write(1,"\n",1);
    j = 1;
    for (i = 0;i < NUMFIELDS;++i) {
      if (j >= line.len) {
				if (!stralloc_copys(&f[i],"")) nomem();
      }
      else {
        k = byte_chr(line.s + j,line.len - j,':');
				if (!stralloc_copyb(&f[i],line.s + j,k)) nomem();
				j += k + 1;
      }
    }

	switch(line.s[0]) {
#ifdef USE_LOCMAPS
	case '%':
		//locparse(&f[0],loc);
		loc = gethash(f[0].s,f[0].len);
		uint32_pack(locp,loc);
		if (!stralloc_0(&f[1])) nomem();
		if (!stralloc_0(&f[2])) nomem();
		ip4_scan(f[1].s,ipa);
		//ip4_scan(f[2].s,ipb);
		scan_ushort(f[2].s,&mask);
		ip4_num(&ipinta,ipa);
		//ip4_num(&ipintb,ipb);
		//if (ipintb<ipinta) nomem();
		//if (ip4_deaggregate(ipinta,ipintb,&subnets,&slen) <= 0) nomem();
		mid = gethash(f[3].s,f[3].len);
		uid = gethash(f[4].s,f[4].len);
		//for (v = 0; v < slen; v++) {
		ipdb_key4build(keyloc,ipinta,(unsigned char )mask&0xff,mid,uid);
		//ipdb_key_from_uint(keyloc,ipinta,(unsigned char )mask&0xff,0,mid,uid);
		cdb_make_add(&cdb,keyloc,15,locp,4);
		//}
		uid = 0;
		//alloc_free(subnets);
		//subnets = NULL;
		//slen = 0;
		byte_zero(ipa,4);ipinta=0; //byte_zero(ipb,4);ipinta=0;ipintb=0;
		break;
#endif
 	case 'Z':
		if (!dns_domain_fromdot(&d1,f[0].s,f[0].len)) nomem();

		if (!stralloc_0(&f[3])) nomem();
		if (!scan_ulong(f[3].s,&u)) uint32_unpack_big(defaultsoa,&u);
		uint32_pack_big(soa,u);
		if (!stralloc_0(&f[4])) nomem();
		if (!scan_ulong(f[4].s,&u)) uint32_unpack_big(defaultsoa + 4,&u);
		uint32_pack_big(soa + 4,u);
		if (!stralloc_0(&f[5])) nomem();
		if (!scan_ulong(f[5].s,&u)) uint32_unpack_big(defaultsoa + 8,&u);
		uint32_pack_big(soa + 8,u);
		if (!stralloc_0(&f[6])) nomem();
		if (!scan_ulong(f[6].s,&u)) uint32_unpack_big(defaultsoa + 12,&u);
		uint32_pack_big(soa + 12,u);
		if (!stralloc_0(&f[7])) nomem();
		if (!scan_ulong(f[7].s,&u)) uint32_unpack_big(defaultsoa + 16,&u);
		uint32_pack_big(soa + 16,u);

		if (!stralloc_0(&f[8])) nomem();
		if (!scan_ulong(f[8].s,&ttl)) ttl = TTL_NEGATIVE;
		ttdparse(&f[9],ttd);
		loc = gethash(f[10].s,f[10].len);
		mid = gethash(f[11].s,f[11].len);
		uid = gethash(f[12].s,f[12].len);
		rr_addloq(DNS_T_SOA,d1,loc,mid,uid);

		rr_start(DNS_T_SOA,ttl,ttd,loc);
		if (!dns_domain_fromdot(&d2,f[1].s,f[1].len)) nomem();
		rr_addname(d2);
		if (!dns_domain_fromdot(&d2,f[2].s,f[2].len)) nomem();
		rr_addname(d2);
		rr_add(soa,20);
		rr_finish(d1);
		break;

	case '.': case '&':
		if (!dns_domain_fromdot(&d1,f[0].s,f[0].len)) nomem();
		if (!stralloc_0(&f[3])) nomem();
		if (!scan_ulong(f[3].s,&ttl)) ttl = TTL_NS;
		ttdparse(&f[4],ttd);
		loc = gethash(f[5].s,f[5].len);
		mid = gethash(f[6].s,f[6].len);
		uid = gethash(f[7].s,f[7].len);

		if (!stralloc_0(&f[1])) nomem();

		if (byte_chr(f[2].s,f[2].len,'.') >= f[2].len) {
			if (!stralloc_cats(&f[2],".ns.")) nomem();
			if (!stralloc_catb(&f[2],f[0].s,f[0].len)) nomem();
		}
		if (!dns_domain_fromdot(&d2,f[2].s,f[2].len)) nomem();

		if (line.s[0] == '.') {
			rr_start(DNS_T_SOA,ttl ? TTL_NEGATIVE : 0,ttd,loc);
			rr_addloq(DNS_T_SOA,d1,loc,mid,uid);
			rr_addname(d2);
			rr_add("\12hostmaster",11);
			rr_addname(d1);
			rr_add(defaultsoa,20);
			rr_finish(d1);
		}

		rr_start(DNS_T_NS,ttl,ttd,loc);
		rr_addname(d2);
		rr_addloq(DNS_T_NS,d2,loc,mid,uid);
		rr_finish(d1);

		if (ip4_scan(f[1].s,ip)) {
	  	rr_start(DNS_T_A,ttl,ttd,loc);
			rr_addloq(DNS_T_A,d2,loc,mid,uid);
			rr_add(ip,4);
			rr_finish(d2);
		}

		break;

	case '+': case '=':
		if (!dns_domain_fromdot(&d1,f[0].s,f[0].len)) nomem();
		if (!stralloc_0(&f[2])) nomem();
		if (!scan_ulong(f[2].s,&ttl)) ttl = TTL_POSITIVE;
		ttdparse(&f[3],ttd);
		loc = gethash(f[4].s,f[4].len);
		mid = gethash(f[5].s,f[5].len);
		uid = gethash(f[6].s,f[6].len);

		if (!stralloc_0(&f[1])) nomem();

		if (ip4_scan(f[1].s,ip)) {
			rr_addloq(DNS_T_A,d1,loc,mid,uid);
			rr_start(DNS_T_A,ttl,ttd,loc);
			//dbger("+addloq:d=%s,loc=%u,uid=%u,mid=%u",d1,loc,uid,mid);
			rr_add(ip,4);
			rr_finish(d1);

			if (line.s[0] == '=') {
				rr_addloq(DNS_T_PTR,d1,loc,mid,uid); //??????????????????/ TODO: checkthis
				dns_name4_domain(dptr,ip);
				rr_start(DNS_T_PTR,ttl,ttd,loc);
				rr_addname(d1);
				rr_finish(dptr);
			}
		}
		break;

	case '@':
		if (!dns_domain_fromdot(&d1,f[0].s,f[0].len)) nomem();
		if (!stralloc_0(&f[4])) nomem();
		if (!scan_ulong(f[4].s,&ttl)) ttl = TTL_POSITIVE;
		ttdparse(&f[5],ttd);
		loc = gethash(f[6].s,f[6].len);
		mid = gethash(f[7].s,f[7].len);
		uid = gethash(f[8].s,f[8].len);

		if (!stralloc_0(&f[1])) nomem();

		if (byte_chr(f[2].s,f[2].len,'.') >= f[2].len) {
			if (!stralloc_cats(&f[2],".mx.")) nomem();
			if (!stralloc_catb(&f[2],f[0].s,f[0].len)) nomem();
		}
		if (!dns_domain_fromdot(&d2,f[2].s,f[2].len)) nomem();

		if (!stralloc_0(&f[3])) nomem();
		if (!scan_ulong(f[3].s,&u)) u = 0;

		rr_addloq(DNS_T_MX,d1,loc,mid,uid);
		rr_start(DNS_T_MX,ttl,ttd,loc);
		uint16_pack_big(buf,u);
		rr_add(buf,2);
		rr_addname(d2);
		rr_finish(d1);

		if (ip4_scan(f[1].s,ip)) {
			rr_addloq(DNS_T_A,d2,loc,mid,uid);
			rr_start(DNS_T_A,ttl,ttd,loc);
			rr_add(ip,4);
			rr_finish(d2);
		}
		break;

	case '^': case 'C':
		if (!dns_domain_fromdot(&d1,f[0].s,f[0].len)) nomem();
		if (!dns_domain_fromdot(&d2,f[1].s,f[1].len)) nomem();
		if (!stralloc_0(&f[2])) nomem();
		if (!scan_ulong(f[2].s,&ttl)) ttl = TTL_POSITIVE;
		ttdparse(&f[3],ttd);
		loc = gethash(f[4].s,f[4].len);
		mid = gethash(f[5].s,f[5].len);
		uid = gethash(f[6].s,f[6].len);

		if (line.s[0] == 'C') {
			//rr_addloq(DNS_T_CNAME,d1,loc,mid,uid);
			//dbger("add loq for cname!");
			rr_addloq(DNS_T_A,d1,loc,mid,uid);
			rr_addloq(DNS_T_CNAME,d1,loc,mid,uid);
			rr_start(DNS_T_CNAME,ttl,ttd,loc);
		} else {
			rr_addloq(DNS_T_PTR,d1,loc,mid,uid);
			rr_start(DNS_T_PTR,ttl,ttd,loc);
		}
		rr_addname(d2);
		rr_finish(d1);
		break;

	case '\'':
		if (!dns_domain_fromdot(&d1,f[0].s,f[0].len)) nomem();
		if (!stralloc_0(&f[2])) nomem();
		if (!scan_ulong(f[2].s,&ttl)) ttl = TTL_POSITIVE;
		ttdparse(&f[3],ttd);
		loc = gethash(f[4].s,f[4].len);
		mid = gethash(f[5].s,f[5].len);
		uid = gethash(f[6].s,f[6].len);

		rr_addloq(DNS_T_TXT,d1,loc,mid,uid);
		rr_start(DNS_T_TXT,ttl,ttd,loc);
		txtparse(&f[1]);
		i = 0;
		while (i < f[1].len) {
			k = f[1].len - i;
			if (k > 127) k = 127;
			ch = k;
			rr_add(&ch,1);
			rr_add(f[1].s + i,k);
			i += k;
		}

		rr_finish(d1);
		break;

	case ':':
		if (!dns_domain_fromdot(&d1,f[0].s,f[0].len)) nomem();
		if (!stralloc_0(&f[3])) nomem();
		if (!scan_ulong(f[3].s,&ttl)) ttl = TTL_POSITIVE;
		ttdparse(&f[4],ttd);
		loc = gethash(f[5].s,f[5].len);
		mid = gethash(f[6].s,f[6].len);
		uid = gethash(f[7].s,f[7].len);

		if (!stralloc_0(&f[1])) nomem();
		scan_ulong(f[1].s,&u);
		uint16_pack_big(type,u);
		if (byte_equal(type,2,DNS_T_AXFR))
			syntaxerror(": type AXFR prohibited");
		if (byte_equal(type,2,"\0\0"))
			syntaxerror(": type 0 prohibited");
		if (byte_equal(type,2,DNS_T_SOA))
			syntaxerror(": type SOA prohibited");
		if (byte_equal(type,2,DNS_T_NS))
			syntaxerror(": type NS prohibited");
		if (byte_equal(type,2,DNS_T_CNAME))
			syntaxerror(": type CNAME prohibited");
		if (byte_equal(type,2,DNS_T_PTR))
			syntaxerror(": type PTR prohibited");
		if (byte_equal(type,2,DNS_T_MX))
			syntaxerror(": type MX prohibited");
		txtparse(&f[2]);
		rr_addloq(type,d1,loc,mid,uid);
		rr_start(type,ttl,ttd,loc);
		rr_add(f[2].s,f[2].len);
		rr_finish(d1);
		break;
	default:
		dienow("error here: %s\n", line.s);
		syntaxerror(": unrecognized leading character");
}
}

  if (cdb_make_finish(&cdb) == -1) die_datatmp();
  if (fsync(fdcdb) == -1) die_datatmp();
  if (close(fdcdb) == -1) die_datatmp(); /* NFS stupidity */
	if (argc  == 3) {
		if (rename(argv[1],argv[2]) == -1) strerr_die2sys(111,FATAL,"unable to move data.tmp to data.cdb: ");
	} else {
		if (rename("data.tmp","data.cdb") == -1) strerr_die2sys(111,FATAL,"unable to move data.tmp to data.cdb: ");
	}

  _exit(0);
}
예제 #24
0
int main()
{
  int fddata;
  int i;
  int j;
  int k;
  char ch;
  unsigned long ttl;
  char ttd[8];
  char loc[2];
  unsigned long u;
  char ip[4];
  char ip6[16];
  char type[2];
  char soa[20];
  char buf[4];

  umask(022);

  fddata = open_read("data");
  if (fddata == -1)
    strerr_die2sys(111,FATAL,"unable to open data: ");
  defaultsoa_init(fddata);

  buffer_init(&b,buffer_unixread,fddata,bspace,sizeof bspace);

  fdcdb = open_trunc("data.tmp");
  if (fdcdb == -1) die_datatmp();
  if (cdb_make_start(&cdb,fdcdb) == -1) die_datatmp();

  while (match) {
    ++linenum;
    if (getln(&b,&line,&match,'\n') == -1)
      strerr_die2sys(111,FATAL,"unable to read line: ");

    while (line.len) {
      ch = line.s[line.len - 1];
      if ((ch != ' ') && (ch != '\t') && (ch != '\n')) break;
      --line.len;
    }
    if (!line.len) continue;
    if (line.s[0] == '#') continue;
    if (line.s[0] == '-') continue;

    j = 1;
    for (i = 0;i < NUMFIELDS;++i) {
      if (j >= line.len) {
	if (!stralloc_copys(&f[i],"")) nomem();
      }
      else {
        k = byte_chr(line.s + j,line.len - j,':');
	if (!stralloc_copyb(&f[i],line.s + j,k)) nomem();
	j += k + 1;
      }
    }

    switch(line.s[0]) {

      case '%':
	locparse(&f[0],loc);
	if (!stralloc_copyb(&key,"\0%",2)) nomem();
	if (!stralloc_0(&f[1])) nomem();
	ipprefix_cat(&key,f[1].s);
        if (cdb_make_add(&cdb,key.s,key.len,loc,2) == -1)
          die_datatmp();
	break;

      case 'Z':
	if (!dns_domain_fromdot(&d1,f[0].s,f[0].len)) nomem();

	if (!stralloc_0(&f[3])) nomem();
	if (!scan_ulong(f[3].s,&u)) uint32_unpack_big(defaultsoa,&u);
	uint32_pack_big(soa,u);
	if (!stralloc_0(&f[4])) nomem();
	if (!scan_ulong(f[4].s,&u)) uint32_unpack_big(defaultsoa + 4,&u);
	uint32_pack_big(soa + 4,u);
	if (!stralloc_0(&f[5])) nomem();
	if (!scan_ulong(f[5].s,&u)) uint32_unpack_big(defaultsoa + 8,&u);
	uint32_pack_big(soa + 8,u);
	if (!stralloc_0(&f[6])) nomem();
	if (!scan_ulong(f[6].s,&u)) uint32_unpack_big(defaultsoa + 12,&u);
	uint32_pack_big(soa + 12,u);
	if (!stralloc_0(&f[7])) nomem();
	if (!scan_ulong(f[7].s,&u)) uint32_unpack_big(defaultsoa + 16,&u);
	uint32_pack_big(soa + 16,u);

	if (!stralloc_0(&f[8])) nomem();
	if (!scan_ulong(f[8].s,&ttl)) ttl = TTL_NEGATIVE;
	ttdparse(&f[9],ttd);
	locparse(&f[10],loc);

	rr_start(DNS_T_SOA,ttl,ttd,loc);
	if (!dns_domain_fromdot(&d2,f[1].s,f[1].len)) nomem();
	rr_addname(d2);
	if (!dns_domain_fromdot(&d2,f[2].s,f[2].len)) nomem();
	rr_addname(d2);
	rr_add(soa,20);
	rr_finish(d1);
	break;

      case '.': case '&':
	if (!dns_domain_fromdot(&d1,f[0].s,f[0].len)) nomem();
	if (!stralloc_0(&f[3])) nomem();
	if (!scan_ulong(f[3].s,&ttl)) ttl = TTL_NS;
	ttdparse(&f[4],ttd);
	locparse(&f[5],loc);

	if (!stralloc_0(&f[1])) nomem();

	if (byte_chr(f[2].s,f[2].len,'.') >= f[2].len) {
	  if (!stralloc_cats(&f[2],".ns.")) nomem();
	  if (!stralloc_catb(&f[2],f[0].s,f[0].len)) nomem();
	}
	if (!dns_domain_fromdot(&d2,f[2].s,f[2].len)) nomem();

	if (line.s[0] == '.') {
	  rr_start(DNS_T_SOA,ttl ? TTL_NEGATIVE : 0,ttd,loc);
	  rr_addname(d2);
	  rr_add("\12hostmaster",11);
	  rr_addname(d1);
	  rr_add(defaultsoa,20);
	  rr_finish(d1);
	}

	rr_start(DNS_T_NS,ttl,ttd,loc);
	rr_addname(d2);
	rr_finish(d1);

	if (ip4_scan(f[1].s,ip)) {
	  rr_start(DNS_T_A,ttl,ttd,loc);
	  rr_add(ip,4);
	  rr_finish(d2);
	}

	break;

      case '+': case '=':
	if (!dns_domain_fromdot(&d1,f[0].s,f[0].len)) nomem();
	if (!stralloc_0(&f[2])) nomem();
	if (!scan_ulong(f[2].s,&ttl)) ttl = TTL_POSITIVE;
	ttdparse(&f[3],ttd);
	locparse(&f[4],loc);

	if (!stralloc_0(&f[1])) nomem();

	if (ip4_scan(f[1].s,ip)) {
	  rr_start(DNS_T_A,ttl,ttd,loc);
	  rr_add(ip,4);
	  rr_finish(d1);

	  if (line.s[0] == '=') {
	    dns_name4_domain(dptr,ip);
	    rr_start(DNS_T_PTR,ttl,ttd,loc);
	    rr_addname(d1);
	    rr_finish(dptr);
	  }
	}
	break;

      case '6': case '3':
	if (!dns_domain_fromdot(&d1,f[0].s,f[0].len)) nomem();
	if (!stralloc_0(&f[2])) nomem();
	if (!scan_ulong(f[2].s,&ttl)) ttl = TTL_POSITIVE;
	ttdparse(&f[3],ttd);
	locparse(&f[4],loc);

	if (!stralloc_0(&f[1])) nomem();
	if (ip6_scan_flat(f[1].s,ip6)) {
	  rr_start(DNS_T_AAAA,ttl,ttd,loc);
	  rr_add(ip6,16);
	  rr_finish(d1);

	  if (line.s[0] == '6') {	/* emit both .ip6.arpa and .ip6.int */
	    dns_name6_domain(d6ptr,ip6,DNS_IP6_ARPA);
	    rr_start(DNS_T_PTR,ttl,ttd,loc);
	    rr_addname(d1);
	    rr_finish(d6ptr);

	    dns_name6_domain(d6ptr,ip6,DNS_IP6_INT);
	    rr_start(DNS_T_PTR,ttl,ttd,loc);
	    rr_addname(d1);
	    rr_finish(d6ptr);
	  }
	}
	break;

      case '@':
	if (!dns_domain_fromdot(&d1,f[0].s,f[0].len)) nomem();
	if (!stralloc_0(&f[4])) nomem();
	if (!scan_ulong(f[4].s,&ttl)) ttl = TTL_POSITIVE;
	ttdparse(&f[5],ttd);
	locparse(&f[6],loc);

	if (!stralloc_0(&f[1])) nomem();

	if (byte_chr(f[2].s,f[2].len,'.') >= f[2].len) {
	  if (!stralloc_cats(&f[2],".mx.")) nomem();
	  if (!stralloc_catb(&f[2],f[0].s,f[0].len)) nomem();
	}
	if (!dns_domain_fromdot(&d2,f[2].s,f[2].len)) nomem();

	if (!stralloc_0(&f[3])) nomem();
	if (!scan_ulong(f[3].s,&u)) u = 0;

	rr_start(DNS_T_MX,ttl,ttd,loc);
	uint16_pack_big(buf,u);
	rr_add(buf,2);
	rr_addname(d2);
	rr_finish(d1);

	if (ip4_scan(f[1].s,ip)) {
	  rr_start(DNS_T_A,ttl,ttd,loc);
	  rr_add(ip,4);
	  rr_finish(d2);
	}
	break;

      case '^': case 'C':
	if (!dns_domain_fromdot(&d1,f[0].s,f[0].len)) nomem();
	if (!dns_domain_fromdot(&d2,f[1].s,f[1].len)) nomem();
	if (!stralloc_0(&f[2])) nomem();
	if (!scan_ulong(f[2].s,&ttl)) ttl = TTL_POSITIVE;
	ttdparse(&f[3],ttd);
	locparse(&f[4],loc);

	if (line.s[0] == 'C')
	  rr_start(DNS_T_CNAME,ttl,ttd,loc);
	else
	  rr_start(DNS_T_PTR,ttl,ttd,loc);
	rr_addname(d2);
	rr_finish(d1);
	break;

      case '\'':
	if (!dns_domain_fromdot(&d1,f[0].s,f[0].len)) nomem();
	if (!stralloc_0(&f[2])) nomem();
	if (!scan_ulong(f[2].s,&ttl)) ttl = TTL_POSITIVE;
	ttdparse(&f[3],ttd);
	locparse(&f[4],loc);

	rr_start(DNS_T_TXT,ttl,ttd,loc);

	txtparse(&f[1]);
	i = 0;
	while (i < f[1].len) {
	  k = f[1].len - i;
	  if (k > 127) k = 127;
	  ch = k;
	  rr_add(&ch,1);
	  rr_add(f[1].s + i,k);
	  i += k;
	}

	rr_finish(d1);
	break;

      case ':':
	if (!dns_domain_fromdot(&d1,f[0].s,f[0].len)) nomem();
	if (!stralloc_0(&f[3])) nomem();
	if (!scan_ulong(f[3].s,&ttl)) ttl = TTL_POSITIVE;
	ttdparse(&f[4],ttd);
	locparse(&f[5],loc);

	if (!stralloc_0(&f[1])) nomem();
	scan_ulong(f[1].s,&u);
	uint16_pack_big(type,u);
	if (byte_equal(type,2,DNS_T_AXFR))
	  syntaxerror(": type AXFR prohibited");
	if (byte_equal(type,2,"\0\0"))
	  syntaxerror(": type 0 prohibited");
	if (byte_equal(type,2,DNS_T_SOA))
	  syntaxerror(": type SOA prohibited");
	if (byte_equal(type,2,DNS_T_NS))
	  syntaxerror(": type NS prohibited");
	if (byte_equal(type,2,DNS_T_CNAME))
	  syntaxerror(": type CNAME prohibited");
	if (byte_equal(type,2,DNS_T_PTR))
	  syntaxerror(": type PTR prohibited");
	if (byte_equal(type,2,DNS_T_MX))
	  syntaxerror(": type MX prohibited");

	txtparse(&f[2]);

	rr_start(type,ttl,ttd,loc);
	rr_add(f[2].s,f[2].len);
	rr_finish(d1);
	break;

      default:
        syntaxerror(": unrecognized leading character");
    }
  }

  if (cdb_make_finish(&cdb) == -1) die_datatmp();
  if (fsync(fdcdb) == -1) die_datatmp();
  if (close(fdcdb) == -1) die_datatmp(); /* NFS stupidity */
  if (rename("data.tmp","data.cdb") == -1)
    strerr_die2sys(111,FATAL,"unable to move data.tmp to data.cdb: ");

  _exit(0);
}
예제 #25
0
int main()
{
    char ip[4];
    unsigned long u;
    unsigned int j;
    unsigned int k;
    char ch;

    umask(022);

    fd = open_read("data");
    if (fd == -1) strerr_die2sys(111,FATAL,"unable to open data: ");
    buffer_init(&b,buffer_unixread,fd,bspace,sizeof bspace);

    fdcdb = open_trunc("data.tmp");
    if (fdcdb == -1) die_datatmp();
    if (cdb_make_start(&cdb,fdcdb) == -1) die_datatmp();

    while (match) {
        ++linenum;
        if (getln(&b,&line,&match,'\n') == -1)
            strerr_die2sys(111,FATAL,"unable to read line: ");

        while (line.len) {
            ch = line.s[line.len - 1];
            if ((ch != ' ') && (ch != '\t') && (ch != '\n')) break;
            --line.len;
        }
        if (!line.len) continue;

        switch(line.s[0]) {
        default:
            syntaxerror(": unrecognized leading character");
        case '#':
            break;
        case ':':
            j = byte_chr(line.s + 1,line.len - 1,':');
            if (j >= line.len - 1) syntaxerror(": missing colon");
            if (ip4_scan(line.s + 1,ip) != j) syntaxerror(": malformed IP address");
            if (!stralloc_copyb(&tmp,ip,4)) nomem();
            if (!stralloc_catb(&tmp,line.s + j + 2,line.len - j - 2)) nomem();
            if (cdb_make_add(&cdb,"",0,tmp.s,tmp.len) == -1)
                die_datatmp();
            break;
        case '0':
        case '1':
        case '2':
        case '3':
        case '4':
        case '5':
        case '6':
        case '7':
        case '8':
        case '9':
            if (!stralloc_0(&line)) nomem();
            j = 0;
            if (!stralloc_copys(&tmp,"")) nomem();
            for (;;) {
                k = scan_ulong(line.s + j,&u);
                if (!k) break;
                ch = u;
                if (!stralloc_catb(&tmp,&ch,1)) nomem();
                j += k;
                if (line.s[j] != '.') break;
                ++j;
            }
            if (!stralloc_catb(&tmp,"\0\0\0\0",4)) nomem();
            tmp.len = 4;
            if (line.s[j] == '/')
                scan_ulong(line.s + j + 1,&u);
            else
                u = 32;
            if (u > 32) u = 32;
            ch = u;
            if (!stralloc_catb(&tmp,&ch,1)) nomem();
            if (cdb_make_add(&cdb,tmp.s,tmp.len,"",0) == -1)
                die_datatmp();
            break;
        }
    }

    if (cdb_make_finish(&cdb) == -1) die_datatmp();
    if (fsync(fdcdb) == -1) die_datatmp();
    if (close(fdcdb) == -1) die_datatmp(); /* NFS stupidity */
    if (rename("data.tmp","data.cdb") == -1)
        strerr_die2sys(111,FATAL,"unable to move data.tmp to data.cdb: ");

    return 0;
}
예제 #26
0
파일: qmail-newu.c 프로젝트: 0xkag/qmail
void main()
{
  int i;
  int numcolons;

  umask(033);
  if (chdir(auto_qmail) == -1) die_chdir();

  fd = open_read("users/assign");
  if (fd == -1) die_opena();

  substdio_fdbuf(&ssin,read,fd,inbuf,sizeof(inbuf));

  fdtemp = open_trunc("users/cdb.tmp");
  if (fdtemp == -1) die_opent();

  if (cdbmss_start(&cdbmss,fdtemp) == -1) die_writet();

  if (!stralloc_copys(&wildchars,"")) die_nomem();

  for (;;) {
    if (getln(&ssin,&line,&match,'\n') != 0) die_reada();
    if (line.len && (line.s[0] == '.')) break;
    if (!match) die_format();

    if (byte_chr(line.s,line.len,'\0') < line.len) die_format();
    i = byte_chr(line.s,line.len,':');
    if (i == line.len) die_format();
    if (i == 0) die_format();
    if (!stralloc_copys(&key,"!")) die_nomem();
    if (line.s[0] == '+') {
      if (!stralloc_catb(&key,line.s + 1,i - 1)) die_nomem();
      case_lowerb(key.s,key.len);
      if (i >= 2)
	if (byte_chr(wildchars.s,wildchars.len,line.s[i - 1]) == wildchars.len)
	  if (!stralloc_append(&wildchars,line.s + i - 1)) die_nomem();
    }
    else {
      if (!stralloc_catb(&key,line.s + 1,i - 1)) die_nomem();
      if (!stralloc_0(&key)) die_nomem();
      case_lowerb(key.s,key.len);
    }

    if (!stralloc_copyb(&data,line.s + i + 1,line.len - i - 1)) die_nomem();

    numcolons = 0;
    for (i = 0;i < data.len;++i)
      if (data.s[i] == ':') {
	data.s[i] = 0;
	if (++numcolons == 6)
	  break;
      }
    if (numcolons < 6) die_format();
    data.len = i;

    if (cdbmss_add(&cdbmss,key.s,key.len,data.s,data.len) == -1) die_writet();
  }

  if (cdbmss_add(&cdbmss,"",0,wildchars.s,wildchars.len) == -1) die_writet();

  if (cdbmss_finish(&cdbmss) == -1) die_writet();
  if (fsync(fdtemp) == -1) die_writet();
  if (close(fdtemp) == -1) die_writet(); /* NFS stupidity */
  if (rename("users/cdb.tmp","users/cdb") == -1) die_rename();

  _exit(0);
}
예제 #27
0
void restart(struct cyclog *d)
{
  struct stat st;
  int fd;
  int flagprocessed;

  if (fchdir(fdstartdir) == -1)
    strerr_die2sys(111,FATAL,"unable to switch to starting directory: ");

  mkdir(d->dir,0700);
  d->fddir = open_read(d->dir);
  if ((d->fddir == -1) || (fchdir(d->fddir) == -1))
    strerr_die4sys(111,FATAL,"unable to open directory ",d->dir,": ");
  coe(d->fddir);

  d->fdlock = open_append("lock");
  if ((d->fdlock == -1) || (lock_exnb(d->fdlock) == -1))
    strerr_die4sys(111,FATAL,"unable to lock directory ",d->dir,": ");
  coe(d->fdlock);

  if (stat("current",&st) == -1) {
    if (errno != error_noent)
      strerr_die4sys(111,FATAL,"unable to stat ",d->dir,"/current: ");
  }
  else
    if (st.st_mode & 0100) {
      fd = open_append("current");
      if (fd == -1)
        strerr_die4sys(111,FATAL,"unable to append to ",d->dir,"/current: ");
      if (fchmod(fd,0644) == -1)
        strerr_die4sys(111,FATAL,"unable to set mode of ",d->dir,"/current: ");
      coe(fd);
      d->fdcurrent = fd;
      d->bytes = st.st_size;
      return;
    }

  unlink("state");
  unlink("newstate");

  flagprocessed = 0;
  if (stat("processed",&st) == -1) {
    if (errno != error_noent)
      strerr_die4sys(111,FATAL,"unable to stat ",d->dir,"/processed: ");
  }
  else if (st.st_mode & 0100)
    flagprocessed = 1;

  if (flagprocessed) {
    unlink("previous");
    finish(d,"processed","s");
  }
  else {
    unlink("processed");
    finish(d,"previous","u");
  }

  finish(d,"current","u");

  fd = open_trunc("state");
  if (fd == -1)
    strerr_die4sys(111,FATAL,"unable to write to ",d->dir,"/state: ");
  close(fd);
  fd = open_append("current");
  if (fd == -1)
    strerr_die4sys(111,FATAL,"unable to write to ",d->dir,"/current: ");
  if (fchmod(fd,0644) == -1)
    strerr_die4sys(111,FATAL,"unable to set mode of ",d->dir,"/current: ");
  coe(fd);
  d->fdcurrent = fd;
  d->bytes = 0;
}
예제 #28
0
int
main (int argc, char *argv[])
{
    char ch = 0;
    struct stat st;
    unsigned long ttl = 0;
    unsigned i = 0, j = 0, k = 0;

    prog = strdup ((d1 = strrchr (argv[0], '/')) != NULL ? d1 + 1 : argv[0]);
    i = check_option (argc, argv);
    argv += i;
    argc -= i;
    d1 = NULL;

    if (argc < 6)
    {
        usage ();
        return -1;
    }

    fn = *argv;

    argv++;
    fnnew = *argv;

    argv++;
    if (str_diff (*argv, "add"))
    {
        usage ();
        return -1;
    }

    argv++;
    if (str_equal (*argv, "ns"))
        mode = '.';
    else if (str_equal (*argv, "childns"))
        mode = '&';
    else if (str_equal (*argv, "host"))
        mode = '=';
    else if (str_equal (*argv, "alias"))
        mode = '+';
    else if (str_equal (*argv, "mx"))
        mode = '@';
    else
        errx (-1, "invalid record type `%s'", *argv);

    argv++;
    if (!dns_domain_fromdot (&target, *argv, str_len (*argv)))
        err (-1, "could not allocate enough memory");

    argv++;
    if (!ip4_scan (*argv, targetip))
        errx (-1, "could not parse IP `%s'", *argv);

    umask(077);

    fd = open_read (fn);
    if (fd == -1)
        err (-1, "could not read from `%s'", fn);
    if (fstat (fd, &st) == -1)
        err (-1, "could not read from `%s'", fn);
    buffer_init (&b, buffer_unixread, fd, bspace, sizeof bspace);

    fdnew = open_trunc (fnnew);
    if (fdnew == -1)
        err (-1, "could not write to `%s'", fnnew);
    if (fchmod (fdnew, st.st_mode & 0644) == -1)
        err (-1, "could not write to `%s'", fnnew);
    buffer_init (&bnew, buffer_unixwrite, fdnew, bnewspace, sizeof bnewspace);

    switch (mode)
    {
    case '.':
    case '&':
        ttl = TTL_NS;
        for (i = 0; i < 26; i++)
        {
            ch = 'a' + i;
            if (!stralloc_copyb (&f[0], &ch, 1))
                err (-1, "could not allocate enough memory");
            if (!stralloc_cats (&f[0], ".ns."))
                err (-1, "could not allocate enough memory");
            if (!dns_domain_todot_cat (&f[0], target))
                err (-1, "could not allocate enough memory");
            if (!dns_domain_fromdot (&names[i], f[0].s, f[0].len))
                err (-1, "could not allocate enough memory");
        }
        break;

    case '+':
    case '=':
        ttl = TTL_POSITIVE;
        break;

    case '@':
        ttl = TTL_POSITIVE;
        for (i = 0; i < 26; i++)
        {
            ch = 'a' + i;
            if (!stralloc_copyb (&f[0], &ch, 1))
                err (-1, "could not allocate enough memory");
            if (!stralloc_cats (&f[0], ".mx."))
                err (-1, "could not allocate enough memory");
            if (!dns_domain_todot_cat (&f[0], target))
                err (-1, "could not allocate enough memory");
            if (!dns_domain_fromdot (&names[i], f[0].s, f[0].len))
                err (-1, "could not allocate enough memory");
        }
        break;
    }

    while (match)
    {
        if (getln (&b, &line, &match, '\n') == -1)
            err (-1, "could not read from `%s'", fn);

        put (line.s, line.len);
        if (line.len && !match)
            put ("\n", 1);

        while (line.len)
        {
            ch = line.s[line.len - 1];
            if ((ch != ' ') && (ch != '\t') && (ch != '\n'))
                break;

            --line.len;
        }
        if (!line.len || line.s[0] == '#')
            continue;

        j = 1;
        for (i = 0; i < NUMFIELDS; i++)
        {
            if (j >= line.len)
            {
                if (!stralloc_copys (&f[i], ""))
                    err (-1, "could not allocate enough memory");
            }
            else
            {
                k = byte_chr (line.s + j, line.len - j, ':');
                if (!stralloc_copyb (&f[i], line.s + j, k))
                    err (-1, "could not allocate enough memory");
                j += k + 1;
            }
        }

        switch(mode)
        {
        case '.':
        case '&':
            if (line.s[0] == mode)
            {
                if (!dns_domain_fromdot (&d1, f[0].s, f[0].len))
                    err (-1, "could not allocate enough memory");
                if (dns_domain_equal (d1, target))
                {
                    if (byte_chr (f[2].s, f[2].len, '.') >= f[2].len)
                    {
                        if (!stralloc_cats (&f[2], ".ns."))
                            err (-1, "could not allocate enough memory");
                        if (!stralloc_catb (&f[2], f[0].s, f[0].len))
                            err (-1, "could not allocate enough memory");
                    }
                    if (!dns_domain_fromdot (&d2, f[2].s, f[2].len))
                        err (-1, "could not allocate enough memory");
                    if (!stralloc_0 (&f[3]))
                        err (-1, "could not allocate enough memory");
                    if (!scan_ulong (f[3].s, &ttl))
                        ttl = TTL_NS;
                    for (i = 0; i < 26; i++)
                    {
                        if (dns_domain_equal (d2, names[i]))
                        {
                            used[i] = 1;
                            break;
                        }
                    }
                }
            }
            break;

        case '=':
            if (line.s[0] == '=')
            {
                if (!dns_domain_fromdot (&d1, f[0].s, f[0].len))
                    err (-1, "could not allocate enough memory");
                if (dns_domain_equal (d1, target))
                    errx (-1, "host name is already used");
                if (!stralloc_0 (&f[1]))
                    err (-1, "could not allocate enough memory");
                if (ip4_scan (f[1].s, ip))
                    if (byte_equal(ip, 4, targetip))
                        errx (-1, "IP address is already used");
            }
            break;

        case '@':
            if (line.s[0] == '@')
            {
                if (!dns_domain_fromdot (&d1, f[0].s, f[0].len))
                    err (-1, "could not allocate enough memory");
                if (dns_domain_equal (d1, target))
                {
                    if (byte_chr (f[2].s, f[2].len, '.') >= f[2].len)
                    {
                        if (!stralloc_cats (&f[2], ".mx."))
                            err (-1, "could not allocate enough memory");
                        if (!stralloc_catb (&f[2], f[0].s, f[0].len))
                            err (-1, "could not allocate enough memory");
                    }
                    if (!dns_domain_fromdot (&d2, f[2].s, f[2].len))
                        err (-1, "could not allocate enough memory");
                    if (!stralloc_0 (&f[4]))
                        err (-1, "could not allocate enough memory");
                    if (!scan_ulong (f[4].s, &ttl))
                        ttl = TTL_POSITIVE;
                    for (i = 0; i < 26; i++)
                    {
                        if (dns_domain_equal (d2, names[i]))
                        {
                            used[i] = 1;
                            break;
                        }
                    }
                }
            }
            break;
        }
    }

    if (!stralloc_copyb (&f[0], &mode, 1))
        err (-1, "could not allocate enough memory");
    if (!dns_domain_todot_cat (&f[0], target))
        err (-1, "could not allocate enough memory");
    if (!stralloc_cats (&f[0], ":"))
        err (-1, "could not allocate enough memory");
    if (!stralloc_catb (&f[0], ipstr, ip4_fmt (ipstr, targetip)))
        err (-1, "could not allocate enough memory");

    switch (mode)
    {
    case '.':
    case '&':
    case '@':
        for (i = 0; i < 26; i++)
        {
            if (!used[i])
                break;
        }
        if (i >= 26)
            errx (-1, "too many records for domain `%s'", target);

        ch = 'a' + i;
        if (!stralloc_cats (&f[0], ":"))
            err (-1, "could not allocate enough memory");
        if (!stralloc_catb (&f[0], &ch, 1))
            err (-1, "could not allocate enough memory");
        if (mode == '@')
            if (!stralloc_cats (&f[0], ":"))
                err (-1, "could not allocate enough memory");

        break;
    }

    if (!stralloc_cats (&f[0], ":"))
        err (-1, "could not allocate enough memory");
    if (!stralloc_catb (&f[0], strnum, fmt_ulong (strnum, ttl)))
        err (-1, "could not allocate enough memory");
    if (!stralloc_cats (&f[0], "\n"))
        err (-1, "could not allocate enough memory");
    put (f[0].s, f[0].len);

    if (buffer_flush (&bnew) == -1)
        err (-1, "could not write to `%s'", fnnew);
    if (fsync (fdnew) == -1)
        err (-1, "could not write to `%s'", fnnew);
    if (close (fdnew) == -1)
        err (-1, "could not write to `%s'", fnnew); /* NFS dorks */

    if (rename (fnnew, fn) == -1)
        err (-1, "could not move `%s' to `%s'", fnnew, fn);

    return 0;
}
예제 #29
0
파일: list-r.c 프로젝트: rsenn/dirlist
int
main(int argc, char* argv[]) {
  stralloc dir = {0, 0, 0};
  int c;
  int digit_optind = 0;
  const char* rel_to = 0;
  int index = 0;
  static const struct longopt opts[] =
  { {"help", 0, 0, 'h'},
    {"list", 0, &opt_list, 1},
    {"numeric", 0, &opt_numeric, 1},
    {"relative", 0, &opt_relative, 1},
    {"output", 1, 0, 'o'},
    {"exclude", 1, 0, 'x'},
    {"time-style", 1, 0, 't'},
    {"dereference", 0, &opt_deref, 1},
    {"min-size", 1, 0, 'm'},
#if WINDOWS
    {"separator", 1, 0, 's'},
#endif
    {0} };

#if WINDOWS && defined(O_BINARY)
  setmode(STDOUT_FILENO, O_BINARY);
#endif

  for(;;) {
    c = getopt_long(argc, argv, "hlnro:x:t:m:", opts, &index);
    if(c == -1)
      break;
    if(c == 0)
      continue;

    switch(c) {
      case 'h': usage(argv[0]); return 0;
      case 'x': {
        char* s = optarg;
        array_catb(&exclude_masks, (void*)&s, sizeof(char*));
        break;
      }
      case 'o': {
        buffer_1->fd = io_err_check(open_trunc(optarg));
        break;
      }
      case 't': {
        opt_timestyle = optarg;
        break;
      }
      case 's': {
        opt_separator = optarg[0];
        break;
      }
      case 'l': opt_list = 1; break;
      case 'L': opt_deref = 1; break;
      case 'n': opt_numeric = 1; break;
      case 'r': opt_relative = 1; break;
      case 'm': scan_ulong(optarg, &opt_minsize); break;
      default: usage(argv[0]); return 1;
    }
  }
  /*
    while(optind < argc) {
      if(!str_diff(argv[optind], "-l") || !str_diff(argv[optind], "--list")) {
        opt_list = 1;
      } else if(!str_diff(argv[optind], "-n") || !str_diff(argv[optind], "--numeric")) {
        opt_numeric = 1;
      } else if(!str_diff(argv[optind], "-r") || !str_diff(argv[optind], "--relative")) {
        relative = 1;
      } else if(!str_diff(argv[optind], "-o") || !str_diff(argv[optind], "--output")) {
        buffer_1->fd = io_err_check(open_trunc(argv[optind + 1]));
        ++optind;
      } else if(!str_diff(argv[optind], "--relative")) {
        relative = 1;
      } else if(!str_diff(argv[optind], "-t") || !str_diff(argv[optind], "--time-style")) {
        optind++;
        opt_timestyle = argv[optind];
      } else {
        break;
      }
      optind++;
    }
    */
  array_catb(&exclude_masks, "\0\0\0\0\0\0\0\0", sizeof(char**));
  print_strarray(buffer_2, &exclude_masks);
  if(optind < argc) {
    while(optind < argc) {
      if(opt_relative)
        opt_relative_to = argv[optind];
      stralloc_copys(&dir, argv[optind]);
      list_dir_internal(&dir, 0);
      optind++;
    }
  } else {
    stralloc_copys(&dir, ".");
    list_dir_internal(&dir, 0);
  }
  return 0;
}
예제 #30
0
int main(int argc,char **argv)
{
  unsigned long ttl;
  struct stat st;
  int i;
  int j;
  int k;
  char ch;

  if (!*argv) die_usage();

  if (!*++argv) die_usage();
  fn = *argv;

  if (!*++argv) die_usage();
  fnnew = *argv;

  if (!*++argv) die_usage();
  if (str_diff(*argv,"add")) die_usage();

  if (!*++argv) die_usage();
  if (str_equal(*argv,"ns")) mode = '.';
  else if (str_equal(*argv,"childns")) mode = '&';
  else if (str_equal(*argv,"host")) mode = '=';
  else if (str_equal(*argv,"host6")) mode = '6';
  else if (str_equal(*argv,"alias")) mode = '+';
  else if (str_equal(*argv,"alias6")) mode = '3';
  else if (str_equal(*argv,"mx")) mode = '@';
  else die_usage();

  if (!*++argv) die_usage();
  if (!dns_domain_fromdot(&target,*argv,str_len(*argv))) nomem();

  if (!*++argv) die_usage();
  if (mode == '6' || mode == '3') {
    if (!ip6_scan(*argv,targetip6)) die_usage();
  } else {
    if (!ip4_scan(*argv,targetip)) die_usage();
  }

  umask(077);

  fd = open_read(fn);
  if (fd == -1) die_read();
  if (fstat(fd,&st) == -1) die_read();
  buffer_init(&b,buffer_unixread,fd,bspace,sizeof bspace);

  fdnew = open_trunc(fnnew);
  if (fdnew == -1) die_write();
  if (fchmod(fdnew,st.st_mode & 0644) == -1) die_write();
  buffer_init(&bnew,buffer_unixwrite,fdnew,bnewspace,sizeof bnewspace);

  switch(mode) {
    case '.': case '&':
      ttl = TTL_NS;
      for (i = 0;i < 26;++i) {
	ch = 'a' + i;
	if (!stralloc_copyb(&f[0],&ch,1)) nomem();
	if (!stralloc_cats(&f[0],".ns.")) nomem();
	if (!dns_domain_todot_cat(&f[0],target)) nomem();
	if (!dns_domain_fromdot(&names[i],f[0].s,f[0].len)) nomem();
      }
      break;
    case '+': case '=': case '6': case '3':
      ttl = TTL_POSITIVE;
      break;
    case '@':
      ttl = TTL_POSITIVE;
      for (i = 0;i < 26;++i) {
	ch = 'a' + i;
	if (!stralloc_copyb(&f[0],&ch,1)) nomem();
	if (!stralloc_cats(&f[0],".mx.")) nomem();
	if (!dns_domain_todot_cat(&f[0],target)) nomem();
	if (!dns_domain_fromdot(&names[i],f[0].s,f[0].len)) nomem();
      }
      break;
  }

  while (match) {
    if (getln(&b,&line,&match,'\n') == -1) die_read();

    put(line.s,line.len);
    if (line.len && !match) put("\n",1);

    while (line.len) {
      ch = line.s[line.len - 1];
      if ((ch != ' ') && (ch != '\t') && (ch != '\n')) break;
      --line.len;
    }
    if (!line.len) continue;
    if (line.s[0] == '#') continue;

    j = 1;
    for (i = 0;i < NUMFIELDS;++i) {
      if (j >= line.len) {
	if (!stralloc_copys(&f[i],"")) nomem();
      }
      else {
        k = byte_chr(line.s + j,line.len - j,':');
	if (!stralloc_copyb(&f[i],line.s + j,k)) nomem();
	j += k + 1;
      }
    }

    switch(mode) {
      case '.': case '&':
	if (line.s[0] == mode) {
          if (!dns_domain_fromdot(&d1,f[0].s,f[0].len)) nomem();
	  if (dns_domain_equal(d1,target)) {
	    if (byte_chr(f[2].s,f[2].len,'.') >= f[2].len) {
	      if (!stralloc_cats(&f[2],".ns.")) nomem();
	      if (!stralloc_catb(&f[2],f[0].s,f[0].len)) nomem();
	    }
	    if (!dns_domain_fromdot(&d2,f[2].s,f[2].len)) nomem();
	    if (!stralloc_0(&f[3])) nomem();
	    if (!scan_ulong(f[3].s,&ttl)) ttl = TTL_NS;
	    for (i = 0;i < 26;++i)
	      if (dns_domain_equal(d2,names[i])) {
	        used[i] = 1;
		break;
	      }
	  }
	}
	break;

      case '=':
	if (line.s[0] == '=') {
	  if (!dns_domain_fromdot(&d1,f[0].s,f[0].len)) nomem();
	  if (dns_domain_equal(d1,target))
	    strerr_die2x(100,FATAL,"host name already used");
	  if (!stralloc_0(&f[1])) nomem();
	  if (ip4_scan(f[1].s,ip))
	    if (byte_equal(ip,4,targetip))
	      strerr_die2x(100,FATAL,"IP address already used");
	}
	break;

      case '6':
	if (line.s[0] == '6') {
	  if (!dns_domain_fromdot(&d1,f[0].s,f[0].len)) nomem();
	  if (dns_domain_equal(d1,target))
	    strerr_die2x(100,FATAL,"host name already used");
	  if (!stralloc_0(&f[1])) nomem();
	  if (ip6_scan(f[1].s,ip6))
	    if (byte_equal(ip,16,targetip6))
	      strerr_die2x(100,FATAL,"IPv6 address already used");
	}
	break;

      case '@':
	if (line.s[0] == '@') {
          if (!dns_domain_fromdot(&d1,f[0].s,f[0].len)) nomem();
	  if (dns_domain_equal(d1,target)) {
	    if (byte_chr(f[2].s,f[2].len,'.') >= f[2].len) {
	      if (!stralloc_cats(&f[2],".mx.")) nomem();
	      if (!stralloc_catb(&f[2],f[0].s,f[0].len)) nomem();
	    }
	    if (!dns_domain_fromdot(&d2,f[2].s,f[2].len)) nomem();
	    if (!stralloc_0(&f[4])) nomem();
	    if (!scan_ulong(f[4].s,&ttl)) ttl = TTL_POSITIVE;
	    for (i = 0;i < 26;++i)
	      if (dns_domain_equal(d2,names[i])) {
	        used[i] = 1;
		break;
	      }
	  }
	}
	break;
    }
  }

  if (!stralloc_copyb(&f[0],&mode,1)) nomem();
  if (!dns_domain_todot_cat(&f[0],target)) nomem();
  if (!stralloc_cats(&f[0],":")) nomem();
  if (mode == '6' || mode == '3') {
    if (!stralloc_catb(&f[0],ip6str,ip6_fmt_flat(ip6str,targetip6))) nomem();
  } else {
    if (!stralloc_catb(&f[0],ipstr,ip4_fmt(ipstr,targetip))) nomem();
  }
  switch(mode) {
    case '.': case '&': case '@':
      for (i = 0;i < 26;++i)
	if (!used[i])
	  break;
      if (i >= 26)
	strerr_die2x(100,FATAL,"too many records for that domain");
      ch = 'a' + i;
      if (!stralloc_cats(&f[0],":")) nomem();
      if (!stralloc_catb(&f[0],&ch,1)) nomem();
      if (mode == '@')
        if (!stralloc_cats(&f[0],":")) nomem();
      break;
  }
  if (!stralloc_cats(&f[0],":")) nomem();
  if (!stralloc_catb(&f[0],strnum,fmt_ulong(strnum,ttl))) nomem();
  if (!stralloc_cats(&f[0],"\n")) nomem();
  put(f[0].s,f[0].len);

  if (buffer_flush(&bnew) == -1) die_write();
  if (fsync(fdnew) == -1) die_write();
  if (close(fdnew) == -1) die_write(); /* NFS dorks */
  if (rename(fnnew,fn) == -1)
    strerr_die6sys(111,FATAL,"unable to move ",fnnew," to ",fn,": ");
  _exit(0);
}