Пример #1
0
int wtmp_logout(const char *line) {
  int fd;
  int len;
  struct stat st;
  uw_tmp ut;

  if ((fd = open_append(UW_TMP_WFILE)) == -1)
    strerr_die4sys(111, FATAL, "unable to open ", UW_TMP_WFILE, ": ");
  if (lock_ex(fd) == -1)
    strerr_die4sys(111, FATAL, "unable to lock ", UW_TMP_WFILE, ": ");

  if (fstat(fd, &st) == -1) {
    close(fd);
    return(-1);
  }
  memset(&ut, 0, sizeof(uw_tmp));
  if ((len =str_len(line)) > sizeof ut.ut_line) len =sizeof ut.ut_line -2;
  byte_copy(ut.ut_line, len, line);
  if (time(&ut.ut_time) == -1) {
    close(fd);
    return(-1);
  }
#ifdef DEAD_PROCESS
  ut.ut_type =DEAD_PROCESS;
#endif
  if (write(fd, &ut, sizeof(uw_tmp)) != sizeof(uw_tmp)) {
    ftruncate(fd, st.st_size);
    close(fd);
    return(-1);
  }
  close(fd);
  return(1);
}
Пример #2
0
int utmp_logout(const char *line) {
  int fd;
  uw_tmp ut;
  int ok =-1;

  if ((fd =open(UW_TMP_UFILE, O_RDWR, 0)) < 0)
    strerr_die4sys(111, FATAL, "unable to open ", UW_TMP_UFILE, ": ");
  if (lock_ex(fd) == -1)
    strerr_die4sys(111, FATAL, "unable to lock: ", UW_TMP_UFILE, ": ");

  while (read(fd, &ut, sizeof(uw_tmp)) == sizeof(uw_tmp)) {
    if (!ut.ut_name[0] || (str_diff(ut.ut_line, line) != 0)) continue;
    memset(ut.ut_name, 0, sizeof ut.ut_name);
    memset(ut.ut_host, 0, sizeof ut.ut_host);
    if (time(&ut.ut_time) == -1) break;
#ifdef DEAD_PROCESS
    ut.ut_type =DEAD_PROCESS;
#endif
    if (lseek(fd, -(off_t)sizeof(uw_tmp), SEEK_CUR) == -1) break;
    if (write(fd, &ut, sizeof(uw_tmp)) != sizeof(uw_tmp)) break;
    ok =1;
    break;
  }
  close(fd);
  return(ok);
}
Пример #3
0
int lockfile(const char *path)
{
  int fd;
  fd = open_append(path);
  if (fd == -1)
    strerr_die4sys(111,FATAL,ERR_OPEN,path,": ");
  if (lock_ex(fd) == -1)
    strerr_die4sys(111,FATAL,ERR_OBTAIN,path,": ");
  return fd;
}
Пример #4
0
void slock(const char *f, unsigned int d, unsigned int x) {
  int fd;

  if ((fd =open_append(f)) == -1) slock_die("unable to open lock", f, x);
  if (d) {
    if (lock_ex(fd) == -1) slock_die("unable to lock", f, x);
    return;
  }
  if (lock_exnb(fd) == -1) slock_die("unable to lock", f, x);
}
Пример #5
0
int main()
{
  int fd;
  int i;

  if (chdir(auto_qmail) == -1)
    strerr_die4sys(111,FATAL,"unable to chdir to ",auto_qmail,": ");
  if (chdir("queue/lock") == -1)
    strerr_die4sys(111,FATAL,"unable to chdir to ",auto_qmail,"/queue/lock: ");

  fd = open_write("tcpto");
  if (fd == -1)
    strerr_die4sys(111,FATAL,"unable to write ",auto_qmail,"/queue/lock/tcpto: ");
  if (lock_ex(fd) == -1)
    strerr_die4sys(111,FATAL,"unable to lock ",auto_qmail,"/queue/lock/tcpto: ");

  substdio_fdbuf(&ss,write,fd,buf,sizeof buf);
  for (i = 0;i < sizeof buf;++i) substdio_put(&ss,"",1);
  if (substdio_flush(&ss) == -1)
    strerr_die4sys(111,FATAL,"unable to clear ",auto_qmail,"/queue/lock/tcpto: ");
  _exit(0);
}
Пример #6
0
	bool critical_session::lock()
	{
		return lock_ex() != 1000;
	}
Пример #7
0
int runsv_main(int argc UNUSED_PARAM, char **argv)
{
	struct stat s;
	int fd;
	int r;
	char buf[256];

	INIT_G();

	dir = single_argv(argv);

	xpiped_pair(selfpipe);
	close_on_exec_on(selfpipe.rd);
	close_on_exec_on(selfpipe.wr);
	ndelay_on(selfpipe.rd);
	ndelay_on(selfpipe.wr);

	sig_block(SIGCHLD);
	bb_signals_recursive_norestart(1 << SIGCHLD, s_child);
	sig_block(SIGTERM);
	bb_signals_recursive_norestart(1 << SIGTERM, s_term);

	xchdir(dir);
	/* bss: svd[0].pid = 0; */
	if (S_DOWN) svd[0].state = S_DOWN; /* otherwise already 0 (bss) */
	if (C_NOOP) svd[0].ctrl = C_NOOP;
	if (W_UP) svd[0].sd_want = W_UP;
	/* bss: svd[0].islog = 0; */
	/* bss: svd[1].pid = 0; */
	gettimeofday_ns(&svd[0].start);
	if (stat("down", &s) != -1)
		svd[0].sd_want = W_DOWN;

	if (stat("log", &s) == -1) {
		if (errno != ENOENT)
			warn_cannot("stat ./log");
	} else {
		if (!S_ISDIR(s.st_mode)) {
			errno = 0;
			warn_cannot("stat log/down: log is not a directory");
		} else {
			haslog = 1;
			svd[1].state = S_DOWN;
			svd[1].ctrl = C_NOOP;
			svd[1].sd_want = W_UP;
			svd[1].islog = 1;
			gettimeofday_ns(&svd[1].start);
			if (stat("log/down", &s) != -1)
				svd[1].sd_want = W_DOWN;
			xpiped_pair(logpipe);
			close_on_exec_on(logpipe.rd);
			close_on_exec_on(logpipe.wr);
		}
	}

	if (mkdir("supervise", 0700) == -1) {
		r = readlink("supervise", buf, sizeof(buf));
		if (r != -1) {
			if (r == sizeof(buf))
				fatal2x_cannot("readlink ./supervise", ": name too long");
			buf[r] = 0;
			mkdir(buf, 0700);
		} else {
			if ((errno != ENOENT) && (errno != EINVAL))
				fatal_cannot("readlink ./supervise");
		}
	}
	svd[0].fdlock = xopen3("log/supervise/lock"+4,
			O_WRONLY|O_NDELAY|O_APPEND|O_CREAT, 0600);
	if (lock_exnb(svd[0].fdlock) == -1)
		fatal_cannot("lock supervise/lock");
	close_on_exec_on(svd[0].fdlock);
	if (haslog) {
		if (mkdir("log/supervise", 0700) == -1) {
			r = readlink("log/supervise", buf, 256);
			if (r != -1) {
				if (r == 256)
					fatal2x_cannot("readlink ./log/supervise", ": name too long");
				buf[r] = 0;
				fd = xopen(".", O_RDONLY|O_NDELAY);
				xchdir("./log");
				mkdir(buf, 0700);
				if (fchdir(fd) == -1)
					fatal_cannot("change back to service directory");
				close(fd);
			}
			else {
				if ((errno != ENOENT) && (errno != EINVAL))
					fatal_cannot("readlink ./log/supervise");
			}
		}
		svd[1].fdlock = xopen3("log/supervise/lock",
				O_WRONLY|O_NDELAY|O_APPEND|O_CREAT, 0600);
		if (lock_ex(svd[1].fdlock) == -1)
			fatal_cannot("lock log/supervise/lock");
		close_on_exec_on(svd[1].fdlock);
	}

	mkfifo("log/supervise/control"+4, 0600);
	svd[0].fdcontrol = xopen("log/supervise/control"+4, O_RDONLY|O_NDELAY);
	close_on_exec_on(svd[0].fdcontrol);
	svd[0].fdcontrolwrite = xopen("log/supervise/control"+4, O_WRONLY|O_NDELAY);
	close_on_exec_on(svd[0].fdcontrolwrite);
	update_status(&svd[0]);
	if (haslog) {
		mkfifo("log/supervise/control", 0600);
		svd[1].fdcontrol = xopen("log/supervise/control", O_RDONLY|O_NDELAY);
		close_on_exec_on(svd[1].fdcontrol);
		svd[1].fdcontrolwrite = xopen("log/supervise/control", O_WRONLY|O_NDELAY);
		close_on_exec_on(svd[1].fdcontrolwrite);
		update_status(&svd[1]);
	}
	mkfifo("log/supervise/ok"+4, 0600);
	fd = xopen("log/supervise/ok"+4, O_RDONLY|O_NDELAY);
	close_on_exec_on(fd);
	if (haslog) {
		mkfifo("log/supervise/ok", 0600);
		fd = xopen("log/supervise/ok", O_RDONLY|O_NDELAY);
		close_on_exec_on(fd);
	}
	for (;;) {
		struct pollfd x[3];
		unsigned deadline;
		char ch;

		if (haslog)
			if (!svd[1].pid && svd[1].sd_want == W_UP)
				startservice(&svd[1]);
		if (!svd[0].pid)
			if (svd[0].sd_want == W_UP || svd[0].state == S_FINISH)
				startservice(&svd[0]);

		x[0].fd = selfpipe.rd;
		x[0].events = POLLIN;
		x[1].fd = svd[0].fdcontrol;
		x[1].events = POLLIN;
		/* x[2] is used only if haslog == 1 */
		x[2].fd = svd[1].fdcontrol;
		x[2].events = POLLIN;
		sig_unblock(SIGTERM);
		sig_unblock(SIGCHLD);
		poll(x, 2 + haslog, 3600*1000);
		sig_block(SIGTERM);
		sig_block(SIGCHLD);

		while (read(selfpipe.rd, &ch, 1) == 1)
			continue;

		for (;;) {
			pid_t child;
			int wstat;

			child = wait_any_nohang(&wstat);
			if (!child)
				break;
			if ((child == -1) && (errno != EINTR))
				break;
			if (child == svd[0].pid) {
				svd[0].wstat = wstat;
				svd[0].pid = 0;
				pidchanged = 1;
				svd[0].ctrl &= ~C_TERM;
				if (svd[0].state != S_FINISH) {
					fd = open_read("finish");
					if (fd != -1) {
						close(fd);
						svd[0].state = S_FINISH;
						update_status(&svd[0]);
						continue;
					}
				}
				svd[0].state = S_DOWN;
				deadline = svd[0].start.tv_sec + 1;
				gettimeofday_ns(&svd[0].start);
				update_status(&svd[0]);
				if (LESS(svd[0].start.tv_sec, deadline))
					sleep(1);
			}
			if (haslog) {
				if (child == svd[1].pid) {
					svd[0].wstat = wstat;
					svd[1].pid = 0;
					pidchanged = 1;
					svd[1].state = S_DOWN;
					svd[1].ctrl &= ~C_TERM;
					deadline = svd[1].start.tv_sec + 1;
					gettimeofday_ns(&svd[1].start);
					update_status(&svd[1]);
					if (LESS(svd[1].start.tv_sec, deadline))
						sleep(1);
				}
			}
		} /* for (;;) */
		if (read(svd[0].fdcontrol, &ch, 1) == 1)
			ctrl(&svd[0], ch);
		if (haslog)
			if (read(svd[1].fdcontrol, &ch, 1) == 1)
				ctrl(&svd[1], ch);

		if (sigterm) {
			ctrl(&svd[0], 'x');
			sigterm = 0;
		}

		if (svd[0].sd_want == W_EXIT && svd[0].state == S_DOWN) {
			if (svd[1].pid == 0)
				_exit(EXIT_SUCCESS);
			if (svd[1].sd_want != W_EXIT) {
				svd[1].sd_want = W_EXIT;
				/* stopservice(&svd[1]); */
				update_status(&svd[1]);
				close(logpipe.wr);
				close(logpipe.rd);
			}
		}
	} /* for (;;) */
	/* not reached */
	return 0;
}
Пример #8
0
int main()
{
  buffer bin;
  buffer bout;
  struct prioq_elt pe;
  int fdoldmbox;
  int fdnewmbox;
  int fd;
  int match;
  int fdlock;

  umask(077);

  mbox = env_get("MAIL");
  if (!mbox) strerr_die2x(111,FATL,"MAIL not set");
  mboxtmp = env_get("MAILTMP");
  if (!mboxtmp) strerr_die2x(111,FATL,"MAILTMP not set");

  if (maildir_chdir() == -1)
    strerr_die1(111,FATAL,&maildir_chdir_err);
  maildir_clean(&filenames);
  if (maildir_scan(&pq,&filenames,1,1) == -1)
    strerr_die1(111,FATAL,&maildir_scan_err);

  if (!prioq_min(&pq,&pe)) _exit(0); /* nothing new */

  fdlock = open_append(mbox);
  if (fdlock == -1)
    strerr_die4sys(111,FATL,"unable to lock ",mbox,": ");
  if (lock_ex(fdlock) == -1)
    strerr_die4sys(111,FATL,"unable to lock ",mbox,": ");

  fdoldmbox = open_read(mbox);
  if (fdoldmbox == -1)
    strerr_die4sys(111,FATL,"unable to read ",mbox,": ");

  fdnewmbox = open_trunc(mboxtmp);
  if (fdnewmbox == -1)
    strerr_die4sys(111,FATL,"unable to create ",mboxtmp,": ");

  buffer_init(&bin,read,fdoldmbox,inbuf,sizeof(inbuf));
  buffer_init(&bout,write,fdnewmbox,outbuf,sizeof(outbuf));

  switch(buffer_copy(&bout,&bin))
  {
    case -2: strerr_die4sys(111,FATL,"unable to read ",mbox,": ");
    case -3: strerr_die4sys(111,FATL,"unable to write to ",mboxtmp,": ");
  }

  while (prioq_min(&pq,&pe))
  {
    prioq_delmin(&pq);
    if (!prioq_insert(&pq2,&pe)) die_nomem();

    fd = open_read(filenames.s + pe.id);
    if (fd == -1)
      strerr_die4sys(111,FATL,"unable to read $MAILDIR/",filenames.s + pe.id,": ");
    buffer_init(&bin,read,fd,inbuf,sizeof(inbuf));

    if (getln(&bin,&line,&match,'\n') != 0)
      strerr_die4sys(111,FATL,"unable to read $MAILDIR/",filenames.s + pe.id,": ");

    if (!stralloc_copys(&ufline,"From XXX ")) die_nomem();
    if (match)
      if (stralloc_starts(&line,"Return-Path: <"))
      {
        if (line.s[14] == '>')
    {
          if (!stralloc_copys(&ufline,"From MAILER-DAEMON ")) die_nomem();
    }
        else
        {
      int i;
         if (!stralloc_ready(&ufline,line.len)) die_nomem();
         if (!stralloc_copys(&ufline,"From ")) die_nomem();
      for (i = 14;i < line.len - 2;++i)
        if ((line.s[i] == ' ') || (line.s[i] == '\t'))
          ufline.s[ufline.len++] = '-';
        else {
          ufline.s[ufline.len++] = line.s[i];
          if (!stralloc_cats(&ufline," ")) die_nomem();
          }
        }
      }
    if (!stralloc_cats(&ufline,myctime(pe.dt))) die_nomem();
    if (buffer_put(&bout,ufline.s,ufline.len) == -1)
      strerr_die4sys(111,FATAL,"unable to write to ",mboxtmp,": ");

    while (match && line.len)
    {
      if (gfrom(line.s,line.len))
        if (buffer_puts(&bout,">") == -1)
          strerr_die4sys(111,FATL,"unable to write to ",mboxtmp,": ");
      if (buffer_put(&bout,line.s,line.len) == -1)
        strerr_die4sys(111,FATL,"unable to write to ",mboxtmp,": ");
      if (!match)
      {
        if (buffer_puts(&bout,"\n") == -1)
          strerr_die4sys(111,FATL,"unable to write to ",mboxtmp,": ");
        break;
      }
      if (getln(&bin,&line,&match,'\n') != 0)
        strerr_die4sys(111,FATL,"unable to read $MAILDIR/",filenames.s + pe.id,": ");
    }
    if (buffer_puts(&bout,"\n"))
      strerr_die4sys(111,FATL,"unable to write to ",mboxtmp,": ");

   close(fd);
  }

  if (buffer_flush(&bout) == -1)
    strerr_die4sys(111,FATL,"unable to write to ",mboxtmp,": ");
  if (fsync(fdnewmbox) == -1)
    strerr_die4sys(111,FATL,"unable to write to ",mboxtmp,": ");
  if (close(fdnewmbox) == -1) /* NFS dorks */
    strerr_die4sys(111,FATL,"unable to write to ",mboxtmp,": ");
  if (rename(mboxtmp,mbox) == -1)
    strerr_die6(111,FATL,"unable to move ",mboxtmp," to ",mbox,": ",&strerr_sys);

  while (prioq_min(&pq2,&pe))
  {
    prioq_delmin(&pq2);
    if (unlink(filenames.s + pe.id) == -1)
      strerr_warn4(WARNING,"$MAILDIR/",filenames.s + pe.id," will be delivered twice; unable to unlink: ",&strerr_sys);
  }

  return(0);
}