Exemplo n.º 1
0
bool GPhotoCCD::grabImage()
{
    //char ext[16];
    uint8_t *memptr = PrimaryCCD.getFrameBuffer();
	size_t memsize;
    int fd, naxis=2, w, h, bpp=8;

    if (sim)
    {

      w= PrimaryCCD.getXRes();
      h= PrimaryCCD.getYRes();
      size_t fullbuf_size = w*h + 512;
      uint8_t * fullbuf = (uint8_t *) malloc(fullbuf_size);
      for (int i = 0; i < h; i++)
        for (int j = 0; j < w; j++)
          fullbuf[i * w + j] = rand() % 255;

      // Starting address if subframing
      memptr = fullbuf + (PrimaryCCD.getSubY() * PrimaryCCD.getXRes()) + PrimaryCCD.getSubX();
      memsize = PrimaryCCD.getSubW() * PrimaryCCD.getSubH() * PrimaryCCD.getBPP()/8;

      PrimaryCCD.setFrameBuffer(memptr);
      PrimaryCCD.setFrameBufferSize(memsize, false);
      //PrimaryCCD.setResolution(w, h);
      //PrimaryCCD.setFrame(0, 0, w, h);
      PrimaryCCD.setNAxis(naxis);
      PrimaryCCD.setBPP(bpp);

      ExposureComplete(&PrimaryCCD);
      return true;

    }

    // If only save to SD Card, let's not upload back to client
    /*if (UploadS[GP_UPLOAD_SDCARD].s == ISS_ON)
    {
        DEBUG(INDI::Logger::DBG_SESSION, "Exposure complete. Image saved to SD Card.");
        ExposureComplete(&PrimaryCCD);
        return true;
    }*/


    if (transferFormatS[0].s == ISS_ON)
    {
	    
        char tmpfile[] = "/tmp/indi_XXXXXX";

        //dcraw can't read from stdin, so we need to write to disk then read it back
        fd = mkstemp(tmpfile);

        int ret = gphoto_read_exposure_fd(gphotodrv, fd);

        if (ret != GP_OK || fd == -1)
        {
            if (fd == -1)
                DEBUGF(INDI::Logger::DBG_ERROR, "Exposure failed to save image. Cannot create temp file %s", tmpfile);
            else
                DEBUGF(INDI::Logger::DBG_ERROR, "Exposure failed to save image... %s", gp_result_as_string(ret));
            unlink(tmpfile);
            return false;
        }

        if (!strcmp(gphoto_get_file_extension(gphotodrv), "unknown"))
        {
                DEBUG(INDI::Logger::DBG_ERROR, "Exposure failed.");
                return false;
        }

        /* We're done exposing */
        DEBUG(INDI::Logger::DBG_SESSION, "Exposure done, downloading image...");
    
    
        if(strcasecmp(gphoto_get_file_extension(gphotodrv), "jpg") == 0 ||
           strcasecmp(gphoto_get_file_extension(gphotodrv), "jpeg") == 0)
        {
                if (read_jpeg(tmpfile, &memptr, &memsize, &naxis, &w, &h))
                {
                    DEBUG(INDI::Logger::DBG_ERROR, "Exposure failed to parse jpeg.");
                    unlink(tmpfile);
                    return false;
                }

                DEBUGF(INDI::Logger::DBG_DEBUG, "read_jpeg: memsize (%d) naxis (%d) w (%d) h (%d) bpp (%d)", memsize, naxis, w, h, bpp);
        }
        else
        {
                if (read_dcraw(tmpfile, &memptr, &memsize, &naxis, &w, &h, &bpp))
                {
                    DEBUG(INDI::Logger::DBG_ERROR, "Exposure failed to parse raw image.");
                    unlink(tmpfile);
                    return false;
                }
		
                DEBUGF(INDI::Logger::DBG_DEBUG, "read_dcraw: memsize (%d) naxis (%d) w (%d) h (%d) bpp (%d)", memsize, naxis, w, h, bpp);

                unlink(tmpfile);
        }

        PrimaryCCD.setImageExtension("fits");

        // If subframing is requested
        if (frameInitialized && (PrimaryCCD.getSubH() < PrimaryCCD.getYRes() || PrimaryCCD.getSubW() < PrimaryCCD.getXRes()))
        {
            int subFrameSize  = PrimaryCCD.getSubW() * PrimaryCCD.getSubH() * bpp/8 * ((naxis == 3) ? 3 : 1);
            int oneFrameSize  = PrimaryCCD.getSubW() * PrimaryCCD.getSubH() * bpp/8;
            uint8_t *subframeBuf = (uint8_t *) malloc(subFrameSize);

            int startY= PrimaryCCD.getSubY();
            int endY  = startY + PrimaryCCD.getSubH();
            int lineW = PrimaryCCD.getSubW() * bpp/8;
            int subX = PrimaryCCD.getSubX();

            if (naxis == 2)
            {
                for (int i=startY ; i < endY; i++)
                    memcpy(subframeBuf + (i - startY) * lineW, memptr + (i * w + subX) * bpp/8 , lineW);
            }
            else
            {
                uint8_t *subR = subframeBuf;
                uint8_t *subG = subframeBuf + oneFrameSize;
                uint8_t *subB = subframeBuf + oneFrameSize * 2;

                uint8_t *startR = memptr;
                uint8_t *startG = memptr + (w * h * bpp/8);
                uint8_t *startB = memptr + (w * h * bpp/8 * 2);

                for (int i=startY; i < endY; i++)
                {
                    memcpy(subR + (i-startY) * lineW, startR + (i * w + subX) * bpp/8 , lineW );
                    memcpy(subG + (i-startY) * lineW, startG + (i * w + subX) * bpp/8 , lineW );
                    memcpy(subB + (i-startY) * lineW, startB + (i * w + subX) * bpp/8 , lineW );
                }
            }

            PrimaryCCD.setFrameBuffer(subframeBuf);
            PrimaryCCD.setFrameBufferSize(subFrameSize, false);
            PrimaryCCD.setResolution(w, h);
            PrimaryCCD.setNAxis(naxis);
            PrimaryCCD.setBPP(bpp);

            ExposureComplete(&PrimaryCCD);

            // Restore old pointer and release memory
            PrimaryCCD.setFrameBuffer(memptr);
            PrimaryCCD.setFrameBufferSize(memsize, false);
            free(subframeBuf);
        }
        else
        {
            // We need to initially set the frame dimensions for the first time since it is unknown at the time of connection.
            frameInitialized = true;

            PrimaryCCD.setFrame(0, 0, w, h);
            PrimaryCCD.setFrameBuffer(memptr);
            PrimaryCCD.setFrameBufferSize(memsize, false);
            PrimaryCCD.setResolution(w, h);
            PrimaryCCD.setNAxis(naxis);
            PrimaryCCD.setBPP(bpp);

            ExposureComplete(&PrimaryCCD);
        }

    }
    else
    {        
        int rc = gphoto_read_exposure(gphotodrv);

        if (rc != 0)
        {
            DEBUG(INDI::Logger::DBG_ERROR, "Failed to expose.");
            return rc;
        }
	
        /* We're done exposing */
         DEBUG(INDI::Logger::DBG_DEBUG, "Exposure done, downloading image...");
         uint8_t *newMemptr = NULL;
         gphoto_get_buffer(gphotodrv, (const char **)&newMemptr, &memsize);
         memptr = (uint8_t *)realloc(memptr, memsize); // We copy the obtained memory pointer to avoid freeing some gphoto memory
         memcpy(memptr, newMemptr, memsize); //

         gphoto_get_dimensions(gphotodrv, &w, &h);

        PrimaryCCD.setImageExtension(gphoto_get_file_extension(gphotodrv));
        if (w > 0 && h > 0)
            PrimaryCCD.setFrame(0, 0, w, h);
        PrimaryCCD.setFrameBuffer(memptr);
        PrimaryCCD.setFrameBufferSize(memsize, false);
        if (w > 0 && h > 0)
            PrimaryCCD.setResolution(w, h);
        PrimaryCCD.setNAxis(naxis);
        PrimaryCCD.setBPP(bpp);

        ExposureComplete(&PrimaryCCD);
    }

    return true;
}
Exemplo n.º 2
0
int
edit(struct disklabel *lp, int f)
{
	int first, ch, fd, error = 0;
	struct disklabel label;
	FILE *fp;
	u_int64_t total_sectors, starting_sector, ending_sector;

	if ((fd = mkstemp(tmpfil)) == -1 || (fp = fdopen(fd, "w")) == NULL) {
		if (fd != -1)
			close(fd);
		warn("%s", tmpfil);
		return (1);
	}
	display(fp, lp, 0, 1);
	fprintf(fp, "\n# Notes:\n");
	fprintf(fp,
"# Up to 16 partitions are valid, named from 'a' to 'p'.  Partition 'a' is\n"
"# your root filesystem, 'b' is your swap, and 'c' should cover your whole\n"
"# disk. Any other partition is free for any use.  'size' and 'offset' are\n"
"# in 512-byte blocks. fstype should be '4.2BSD', 'swap', or 'none' or some\n"
"# other values.  fsize/bsize/cpg should typically be '2048 16384 16' for a\n"
"# 4.2BSD filesystem (or '512 4096 16' except on alpha, sun4, ...)\n");
	fclose(fp);
	for (;;) {
		if (editit(tmpfil) == -1)
			break;
		fp = fopen(tmpfil, "r");
		if (fp == NULL) {
			warn("%s", tmpfil);
			break;
		}
		/* Get values set by OS and not the label. */
		if (ioctl(f, DIOCGPDINFO, &label) < 0)
			err(4, "ioctl DIOCGPDINFO");
		ending_sector = DL_GETBEND(&label);
		starting_sector = DL_GETBSTART(&label);
		total_sectors = DL_GETDSIZE(&label);
		memset(&label, 0, sizeof(label));
		error = getasciilabel(fp, &label);
		DL_SETBEND(&label, ending_sector);
		DL_SETBSTART(&label, starting_sector);
		DL_SETDSIZE(&label, total_sectors);

		if (error == 0) {
			if (cmplabel(lp, &label) == 0) {
				puts("No changes.");
				fclose(fp);
				(void) unlink(tmpfil);
				return (0);
			}
			*lp = label;
			if (writelabel(f, bootarea, lp) == 0) {
				fclose(fp);
				(void) unlink(tmpfil);
				return (0);
			}
		}
		fclose(fp);
		printf("re-edit the label? [y]: ");
		fflush(stdout);
		first = ch = getchar();
		while (ch != '\n' && ch != EOF)
			ch = getchar();
		if (first == 'n' || first == 'N')
			break;
	}
	(void)unlink(tmpfil);
	return (1);
}
Exemplo n.º 3
0
FILE *
opencal(void)
{
	uid_t uid;
	size_t i;
	int fd, found, pdes[2];
	struct stat sbuf;

	/* open up calendar file as stdin */
	if (!freopen(calendarFile, "r", stdin)) {
		if (doall) {
			if (chdir(calendarHomes[0]) != 0)
				return (NULL);
			if (stat(calendarNoMail, &sbuf) == 0)
				return (NULL);
			if (!freopen(calendarFile, "r", stdin))
				return (NULL);
		} else {
			char *home = getenv("HOME");
			if (home == NULL || *home == '\0')
				errx(1, "cannot get home directory");
			if (chdir(home) != 0)
				errx(1, "cannot enter home directory");
			for (found = i = 0; i < sizeof(calendarHomes) /
			    sizeof(calendarHomes[0]); i++)
				if (chdir(calendarHomes[i]) == 0 &&
				    freopen(calendarFile, "r", stdin)) {
					found = 1;
					break;
				}
			if (!found)
				errx(1,
				    "can't open calendar file \"%s\": %s (%d)",
				    calendarFile, strerror(errno), errno);
		}
	}
	if (pipe(pdes) < 0)
		return (NULL);
	switch (fork()) {
	case -1:			/* error */
		(void)close(pdes[0]);
		(void)close(pdes[1]);
		return (NULL);
	case 0:
		/* child -- stdin already setup, set stdout to pipe input */
		if (pdes[1] != STDOUT_FILENO) {
			(void)dup2(pdes[1], STDOUT_FILENO);
			(void)close(pdes[1]);
		}
		(void)close(pdes[0]);
		uid = geteuid();
		if (setuid(getuid()) < 0) {
			warnx("first setuid failed");
			_exit(1);
		};
		if (setgid(getegid()) < 0) {
			warnx("setgid failed");
			_exit(1);
		}
		if (setuid(uid) < 0) {
			warnx("setuid failed");
			_exit(1);
		}
		execl(_PATH_CPP, "cpp", "-P",
		    "-traditional", "-nostdinc",	/* GCC specific opts */
		    "-I.", "-I", _PATH_INCLUDE, (char *)NULL);
		warn(_PATH_CPP);
		_exit(1);
	}
	/* parent -- set stdin to pipe output */
	(void)dup2(pdes[0], STDIN_FILENO);
	(void)close(pdes[0]);
	(void)close(pdes[1]);

	/* not reading all calendar files, just set output to stdout */
	if (!doall)
		return (stdout);

	/* set output to a temporary file, so if no output don't send mail */
	(void)snprintf(path, sizeof(path), "%s/_calXXXXXX", _PATH_TMP);
	if ((fd = mkstemp(path)) < 0)
		return (NULL);
	return (fdopen(fd, "w+"));
}
Exemplo n.º 4
0
static MMAPString * mmap_string_realloc_file(MMAPString * string)
{
  char * data;

  if (string->fd == -1) {
    char tmpfilename[PATH_MAX];
    int fd;

    * tmpfilename = 0;
    strcat(tmpfilename, tmpdir);
    strcat(tmpfilename, "/libetpan-mmapstring-XXXXXX");

    fd = mkstemp(tmpfilename);
    if (fd == -1)
      return NULL;

    if (unlink(tmpfilename) == -1) {
      close(fd);
      return NULL;
    }

    if (ftruncate(fd, string->allocated_len) == -1) {
      close(fd);
      return NULL;
    }

    data = mmap(NULL, string->allocated_len, PROT_WRITE | PROT_READ,
		MAP_SHARED, fd, 0);

    if (data == MAP_FAILED) {
      close(fd);
      return NULL;
    }

    if (string->str != NULL)
      memcpy(data, string->str, string->len + 1);

    string->fd = fd;
    string->mmapped_size = string->allocated_len;
    free(string->str);
    string->str = data;
  }
  else {
    if (munmap(string->str, string->mmapped_size) == -1)
      return NULL;

    if (ftruncate(string->fd, string->allocated_len) == -1)
      return NULL;
    
    data = mmap(NULL, string->allocated_len, PROT_WRITE | PROT_READ,
		MAP_SHARED, string->fd, 0);

    if (data == MAP_FAILED)
      return NULL;

    string->mmapped_size = string->allocated_len;
    string->str = data;
  }
  
  return string;
}
Exemplo n.º 5
0
void
do_ranlib (const char *archive)
{
  FILE *infp;

  if (NULL == (infp = fopen (archive, "rb")))
    {
      fprintf (stderr, "asranlib: %s: ", archive);
      perror (NULL);
      exit (1);
    }

  if (!get_symbols (infp, archive))
    {
      fprintf (stderr, "asranlib: %s: Malformed archive\n", archive);
      fclose (infp);
      exit (1);
    }
  else if (!list && !print_index)
    {
      FILE *outfp;
      struct symbol_s *symp;
      char buf[4];
      int str_length;
      int pad;
      int nsym;
      int symtab_size;
      char tmpfile[] = "arXXXXXX";
      struct stat stat_buf;
      int can_stat;

#ifdef _WIN32
      if (NULL == _mktemp (tmpfile) || NULL == (outfp = fopen (tmpfile, "wb")))
        {
          fclose (infp);
          fprintf (stderr, "asranlib: %s: ", tmpfile);
          perror (NULL);
          exit (1);
        }
#else
      if ((pad = mkstemp (tmpfile)) < 0)
        {
          fclose (infp);
          fprintf (stderr, "asranlib: %s: ", tmpfile);
          perror (NULL);
          exit (1);
        }

      if (NULL == (outfp = fdopen (pad, "wb")))
        {
          close (pad);
          fclose (infp);
          perror ("asranlib");
          exit (1);
        }
#endif

      /* calculate the size of symbol table */
      for (str_length = 0, nsym = 0, symp = symlist; symp; ++nsym, symp = symp->next)
        {
          str_length += strlen (symp->name) + 1;
        }

      symtab_size = 4 + 4 * nsym + str_length;

      fprintf (outfp, ARMAG AR_SYMBOL_TABLE_NAME "%-12d%-6d%-6d%-8d%-10d" ARFMAG, (int) time (NULL), 0, 0, 0, symtab_size);

      if (symtab_size & 1)
        {
          pad = 1;
          ++symtab_size;
        }
      else
        pad = 0;

      symtab_size += SARMAG + ARHDR_LEN;

      sputl (nsym, buf);
      fwrite (buf, 1, sizeof (buf), outfp);

      for (symp = symlist; symp; symp = symp->next)
        {
          sputl (symp->offset + symtab_size, buf);
          fwrite (buf, 1, sizeof (buf), outfp);
        }

      for (symp = symlist; symp; symp = symp->next)
        {
          fputs (symp->name, outfp);
          putc ('\0', outfp);
        }

      if (pad)
        putc ('\n', outfp);

      fseek (infp, first_member_offset, SEEK_SET);

      while (EOF != (pad = getc (infp)))
        putc (pad, outfp);

      fclose (outfp);

      if (0 != fstat(fileno(infp), &stat_buf))
        {
          fprintf (stderr, "asranlib: can't stat %s: ", archive);
          perror (NULL);
          can_stat = 0;
        }
      else
        can_stat = 1;

      fclose (infp);

      if (0 != remove (archive))
        {
          fprintf (stderr, "asranlib: can't remove %s: ", archive);
          perror (NULL);
        }
      else if (0 != rename (tmpfile, archive))
        {
          fprintf (stderr, "asranlib: can't rename %s to %s: ", tmpfile, archive);
          perror (NULL);
        }
      else if (!can_stat || 0 != chmod (archive, stat_buf.st_mode))
        {
          fprintf (stderr, "asranlib: can't chmod %s: ", archive);
          perror (NULL);
        }
    }
  else
    fclose (infp);
}
Exemplo n.º 6
0
static int
do_test (void)
{
  int fd;
  char fname[] = "/tmp/tst-perror.XXXXXX";
  int result = 0;
  char buf[200];
  ssize_t n;

  fd = mkstemp (fname);
  if (fd == -1)
    error (EXIT_FAILURE, errno, "cannot create temporary file");

  /* Make sure the file gets removed.  */
  unlink (fname);

  fclose (stderr);

  if (dup2 (fd, 2) == -1)
    {
      printf ("cannot create file descriptor 2: %m\n");
      exit (EXIT_FAILURE);
    }

  stderr = fdopen (2, "w");
  if (stderr == NULL)
    {
      printf ("fdopen failed: %m\n");
      exit (EXIT_FAILURE);
    }

  if (fwide (stderr, 0) != 0)
    {
      printf ("stderr not initially in mode 0\n");
      exit (EXIT_FAILURE);
    }

  errno = EILSEQ;
  perror ("null mode test 1");

  if (fwide (stderr, 0) != 0)
    {
      puts ("perror changed the mode from 0");
      result = 1;
    }

  fputs ("multibyte string\n", stderr);

  if (fwide (stderr, 0) >= 0)
    {
      puts ("fputs didn't set orientation to narrow");
      result = 1;
    }

  errno = EINVAL;
  perror ("<0 mode test");

  fclose (stderr);

  lseek (fd, 0, SEEK_SET);
  n = read (fd, buf, sizeof (buf));
  if (n != MB_EXP_LEN || memcmp (buf, MB_EXP, MB_EXP_LEN) != 0)
    {
      printf ("multibyte test failed.  Expected:\n%s\nGot:\n%.*s\n",
	      MB_EXP, (int) n, buf);
      result = 1;
    }
  else
    puts ("multibyte test succeeded");

  lseek (fd, 0, SEEK_SET);
  ftruncate (fd, 0);

  if (dup2 (fd, 2) == -1)
    {
      printf ("cannot create file descriptor 2: %m\n");
      exit (EXIT_FAILURE);
    }
  stderr = fdopen (2, "w");
  if (stderr == NULL)
    {
      printf ("fdopen failed: %m\n");
      exit (EXIT_FAILURE);
    }

  if (fwide (stderr, 0) != 0)
    {
      printf ("stderr not initially in mode 0\n");
      exit (EXIT_FAILURE);
    }

  errno = EILSEQ;
  perror ("null mode test 2");

  if (fwide (stderr, 0) != 0)
    {
      puts ("perror changed the mode from 0");
      result = 1;
    }

  fputws (L"wide string\n", stderr);

  if (fwide (stderr, 0) <= 0)
    {
      puts ("fputws didn't set orientation to wide");
      result = 1;
    }

  errno = EINVAL;
  perror (">0 mode test");

  fclose (stderr);

  lseek (fd, 0, SEEK_SET);
  n = read (fd, buf, sizeof (buf));
  if (n != WC_EXP_LEN || memcmp (buf, WC_EXP, WC_EXP_LEN) != 0)
    {
      printf ("wide test failed.  Expected:\n%s\nGot:\n%.*s\n",
	      WC_EXP, (int) n, buf);
      result = 1;
    }
  else
    puts ("wide test succeeded");

  close (fd);

  return result;
}
Exemplo n.º 7
0
static int
do_test (void)
{
    int result = 0;

    char tmpfname[] = "/tmp/tst-mqueue5-barrier.XXXXXX";
    int fd = mkstemp (tmpfname);
    if (fd == -1)
    {
        printf ("cannot open temporary file: %m\n");
        return 1;
    }

    /* Make sure it is always removed.  */
    unlink (tmpfname);

    /* Create one page of data.  */
    size_t ps = sysconf (_SC_PAGESIZE);
    char data[ps];
    memset (data, '\0', ps);

    /* Write the data to the file.  */
    if (write (fd, data, ps) != (ssize_t) ps)
    {
        puts ("short write");
        return 1;
    }

    void *mem = mmap (NULL, ps, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
    if (mem == MAP_FAILED)
    {
        printf ("mmap failed: %m\n");
        return 1;
    }

    pthread_barrier_t *b2;
    b2 = (pthread_barrier_t *) (((uintptr_t) mem + __alignof (pthread_barrier_t))
                                & ~(__alignof (pthread_barrier_t) - 1));

    pthread_barrier_t *b3;
    b3 = b2 + 1;

    pthread_barrierattr_t a;
    if (pthread_barrierattr_init (&a) != 0)
    {
        puts ("barrierattr_init failed");
        return 1;
    }

    if (pthread_barrierattr_setpshared (&a, PTHREAD_PROCESS_SHARED) != 0)
    {
        puts ("barrierattr_setpshared failed, could not test");
        return 0;
    }

    if (pthread_barrier_init (b2, &a, 2) != 0)
    {
        puts ("barrier_init failed");
        return 1;
    }

    if (pthread_barrier_init (b3, &a, 3) != 0)
    {
        puts ("barrier_init failed");
        return 1;
    }

    if (pthread_barrierattr_destroy (&a) != 0)
    {
        puts ("barrierattr_destroy failed");
        return 1;
    }

    char name[sizeof "/tst-mqueue5-" + sizeof (pid_t) * 3];
    snprintf (name, sizeof (name), "/tst-mqueue5-%u", getpid ());

    struct mq_attr attr = { .mq_maxmsg = 1, .mq_msgsize = 1 };
    mqd_t q = mq_open (name, O_CREAT | O_EXCL | O_RDWR, 0600, &attr);

    if (q == (mqd_t) -1)
    {
        printf ("mq_open failed with: %m\n");
        return result;
    }
    else
        add_temp_mq (name);

    struct sigevent ev;
    memset (&ev, 0xaa, sizeof (ev));
    ev.sigev_notify = SIGEV_NONE;
    if (mq_notify (q, &ev) != 0)
    {
        printf ("mq_notify (q, { SIGEV_NONE }) failed with: %m\n");
        result = 1;
    }

    if (mq_notify (q, &ev) == 0)
    {
        puts ("second mq_notify (q, { SIGEV_NONE }) unexpectedly succeeded");
        result = 1;
    }
    else if (errno != EBUSY)
    {
        printf ("second mq_notify (q, { SIGEV_NONE }) failed with: %m\n");
        result = 1;
    }

    result |= mqsend (q);

    if (mq_notify (q, &ev) != 0)
    {
        printf ("third mq_notify (q, { SIGEV_NONE }) failed with: %m\n");
        result = 1;
    }

    result |= mqrecv (q);

    if (mq_notify (q, NULL) != 0)
    {
        printf ("mq_notify (q, NULL) failed with: %m\n");
        result = 1;
    }

    if (mq_notify (q, NULL) != 0)
    {
        /* Implementation-defined behaviour, so don't fail,
        just inform.  */
        printf ("second mq_notify (q, NULL) failed with: %m\n");
    }

    struct sigaction sa = { .sa_sigaction = rtmin_handler,
               .sa_flags = SA_SIGINFO
    };
    sigemptyset (&sa.sa_mask);
    sigaction (SIGRTMIN, &sa, NULL);

    memset (&ev, 0x55, sizeof (ev));
    ev.sigev_notify = SIGEV_SIGNAL;
    ev.sigev_signo = SIGRTMIN;
    ev.sigev_value.sival_int = 26;
    if (mq_notify (q, &ev) != 0)
    {
        printf ("mq_notify (q, { SIGEV_SIGNAL }) failed with: %m\n");
        result = 1;
    }

    ev.sigev_value.sival_ptr = &ev;
    if (mq_notify (q, &ev) == 0)
    {
        puts ("second mq_notify (q, { SIGEV_SIGNAL }) unexpectedly succeeded");
        result = 1;
    }
    else if (errno != EBUSY)
    {
        printf ("second mq_notify (q, { SIGEV_SIGNAL }) failed with: %m\n");
        result = 1;
    }

    if (rtmin_cnt != 0)
    {
        puts ("SIGRTMIN signal caught too early");
        result = 1;
    }

    result |= mqsend (q);

    if (rtmin_cnt != 1)
    {
        puts ("SIGRTMIN signal did not arrive");
        result = 1;
    }
    else if (rtmin_pid != getpid ()
             || rtmin_uid != getuid ()
             || rtmin_code != SI_MESGQ
             || rtmin_sigval.sival_int != 26)
    {
        printf ("unexpected siginfo_t fields: pid %u (%u), uid %u (%u), code %d (%d), si_int %d (26)\n",
                rtmin_pid, getpid (), rtmin_uid, getuid (),
                rtmin_code, SI_MESGQ, rtmin_sigval.sival_int);
        result = 1;
    }

    ev.sigev_value.sival_int = 75;
    if (mq_notify (q, &ev) != 0)
    {
        printf ("third mq_notify (q, { SIGEV_SIGNAL }) failed with: %m\n");
        result = 1;
    }

    result |= mqrecv (q);

    if (mq_notify (q, NULL) != 0)
    {
        printf ("mq_notify (q, NULL) failed with: %m\n");
        result = 1;
    }

    memset (&ev, 0x33, sizeof (ev));
    ev.sigev_notify = SIGEV_NONE;
    if (mq_notify (q, &ev) != 0)
    {
        printf ("fourth mq_notify (q, { SIGEV_NONE }) failed with: %m\n");
        result = 1;
    }

    pid_t pid = fork ();
    if (pid == -1)
    {
        printf ("fork () failed: %m\n");
        mq_unlink (name);
        return 1;
    }

    if (pid == 0)
        do_child (name, b2, b3, q);

    /* Child unsuccessfully attempts to mq_notify.  */

    (void) pthread_barrier_wait (b2);

    result |= mqsend (q);

    (void) pthread_barrier_wait (b2);

    /* Child successfully calls mq_notify SIGEV_SIGNAL now.  */

    result |= mqrecv (q);

    (void) pthread_barrier_wait (b2);

    memset (&ev, 0xbb, sizeof (ev));
    ev.sigev_notify = SIGEV_SIGNAL;
    ev.sigev_signo = SIGRTMIN;
    ev.sigev_value.sival_int = 15;
    if (mq_notify (q, &ev) == 0)
    {
        puts ("fourth mq_notify (q, { SIGEV_SIGNAL }) unexpectedly succeeded");
        result = 1;
    }
    else if (errno != EBUSY)
    {
        printf ("fourth mq_notify (q, { SIGEV_SIGNAL }) failed with: %m\n");
        result = 1;
    }

    result |= mqsend (q);

    if (mq_notify (q, &ev) != 0)
    {
        printf ("fifth mq_notify (q, { SIGEV_SIGNAL }) failed with: %m\n");
        result = 1;
    }

    if (rtmin_cnt != 1)
    {
        puts ("SIGRTMIN signal caught too early");
        result = 1;
    }

    result |= mqrecv (q);

    (void) pthread_barrier_wait (b2);

    /* Child verifies caught SIGRTMIN signal.  */
    /* Child calls mq_send (q) which triggers SIGRTMIN signal here.  */

    (void) pthread_barrier_wait (b2);

    /* Child mq_open's another mqd_t for the same queue (q2).  */

    if (rtmin_cnt != 2)
    {
        puts ("SIGRTMIN signal did not arrive");
        result = 1;
    }
    else if (rtmin_pid != pid
             || rtmin_uid != getuid ()
             || rtmin_code != SI_MESGQ
             || rtmin_sigval.sival_int != 15)
    {
        printf ("unexpected siginfo_t fields: pid %u (%u), uid %u (%u), code %d (%d), si_int %d (15)\n",
                rtmin_pid, pid, rtmin_uid, getuid (),
                rtmin_code, SI_MESGQ, rtmin_sigval.sival_int);
        result = 1;
    }

    result |= mqrecv (q);

    (void) pthread_barrier_wait (b2);

    /* Child successfully calls mq_notify { SIGEV_SIGNAL } on q2.  */

    (void) pthread_barrier_wait (b2);

    memset (&ev, 0xbb, sizeof (ev));
    ev.sigev_notify = SIGEV_NONE;
    if (mq_notify (q, &ev) == 0)
    {
        puts ("fifth mq_notify (q, { SIGEV_NONE }) unexpectedly succeeded");
        result = 1;
    }
    else if (errno != EBUSY)
    {
        printf ("fifth mq_notify (q, { SIGEV_NONE }) failed with: %m\n");
        result = 1;
    }

    (void) pthread_barrier_wait (b2);

    /* Child calls mq_close on q2, which makes the queue available again for
       notification.  */

    mqd_t q3 = mq_open (name, O_RDWR);
    if (q3 == (mqd_t) -1)
    {
        printf ("mq_open q3 in parent failed with: %m\n");
        result = 1;
    }

    (void) pthread_barrier_wait (b2);

    memset (&ev, 0x12, sizeof (ev));
    ev.sigev_notify = SIGEV_NONE;
    if (mq_notify (q3, &ev) != 0)
    {
        printf ("mq_notify (q3, { SIGEV_NONE }) failed with: %m\n");
        result = 1;
    }

    (void) pthread_barrier_wait (b2);

    /* Child unsuccessfully attempts to mq_notify { SIGEV_SIGNAL } on q.  */

    (void) pthread_barrier_wait (b2);

    if (mq_close (q3) != 0)
    {
        printf ("mq_close failed: %m\n");
        result = 1;
    }

    (void) pthread_barrier_wait (b2);

    /* Child successfully calls mq_notify { SIGEV_NONE } on q.  */
    /* Child successfully calls mq_notify NULL on q.  */

    (void) pthread_barrier_wait (b2);

    /* Child creates new thread.  */
    /* Thread blocks on mqrecv (q).  */
    /* Child sleeps for 1sec so that thread has time to reach that point.  */
    /* Child successfully calls mq_notify { SIGEV_SIGNAL } on q.  */

    (void) pthread_barrier_wait (b2);

    result |= mqsend (q);

    (void) pthread_barrier_wait (b3);

    /* Child verifies SIGRTMIN has not been sent.  */

    (void) pthread_barrier_wait (b3);

    result |= mqsend (q);

    (void) pthread_barrier_wait (b3);

    /* Thread verifies SIGRTMIN has been caught.  */
    /* Thread calls mq_notify (q, { SIGEV_NONE }) to verify notification is now
       available for registration.  */
    /* Thread calls mq_notify (q, NULL).  */

    (void) pthread_barrier_wait (b3);

    /* Child calls mq_notify (q, { SIGEV_SIGNAL }).  */

    (void) pthread_barrier_wait (b3);

    /* Thread calls mq_notify (q, NULL). */

    (void) pthread_barrier_wait (b3);

    result |= mqsend (q);
    result |= mqrecv (q);

    (void) pthread_barrier_wait (b3);

    /* Child verifies SIGRTMIN has not been sent.  */
    /* Child calls mq_notify (q, { SIGEV_SIGNAL }).  */

    (void) pthread_barrier_wait (b3);

    /* Thread opens a new O_RDONLY mqd_t (q4).  */
    /* Thread calls mq_notify (q4, NULL). */
    /* Thread calls mq_close (q4).  */

    (void) pthread_barrier_wait (b3);

    result |= mqsend (q);
    result |= mqrecv (q);

    (void) pthread_barrier_wait (b3);

    /* Child verifies SIGRTMIN has not been sent.  */
    /* Child calls mq_notify (q, { SIGEV_SIGNAL }).  */

    (void) pthread_barrier_wait (b3);

    /* Thread opens a new O_WRONLY mqd_t (q5).  */
    /* Thread calls mq_notify (q5, NULL). */
    /* Thread calls mq_close (q5).  */

    (void) pthread_barrier_wait (b3);

    result |= mqsend (q);
    result |= mqrecv (q);

    (void) pthread_barrier_wait (b3);

    /* Child verifies SIGRTMIN has not been sent.  */

    int status;
    if (TEMP_FAILURE_RETRY (waitpid (pid, &status, 0)) != pid)
    {
        puts ("waitpid failed");
        kill (pid, SIGKILL);
        result = 1;
    }
    else if (!WIFEXITED (status) || WEXITSTATUS (status))
    {
        printf ("child failed with status %d\n", status);
        result = 1;
    }

    if (mq_unlink (name) != 0)
    {
        printf ("mq_unlink failed: %m\n");
        result = 1;
    }

    if (mq_close (q) != 0)
    {
        printf ("mq_close failed: %m\n");
        result = 1;
    }

    if (mq_notify (q, NULL) == 0)
    {
        puts ("mq_notify on closed mqd_t unexpectedly succeeded");
        result = 1;
    }
    else if (errno != EBADF)
    {
        printf ("mq_notify on closed mqd_t did not fail with EBADF: %m\n");
        result = 1;
    }

    memset (&ev, 0x55, sizeof (ev));
    ev.sigev_notify = SIGEV_NONE;
    if (mq_notify (q, &ev) == 0)
    {
        puts ("mq_notify on closed mqd_t unexpectedly succeeded");
        result = 1;
    }
    else if (errno != EBADF)
    {
        printf ("mq_notify on closed mqd_t did not fail with EBADF: %m\n");
        result = 1;
    }

    return result;
}
Exemplo n.º 8
0
/*
 * Run an editor on the file at "fpp" of "size" bytes,
 * and return a new file pointer.
 * Signals must be handled by the caller.
 * "Type" is 'e' for _PATH_EX, 'v' for _PATH_VI.
 */
FILE *
run_editor(FILE *fp, off_t size, int type, int readonly)
{
	FILE *nf = NULL;
	int t;
	time_t modtime;
	char *edit, tempname[PATHSIZE];
	struct stat statb;

	(void)snprintf(tempname, sizeof(tempname),
	    "%s/mail.ReXXXXXXXXXX", tmpdir);
	if ((t = mkstemp(tempname)) == -1 ||
	    (nf = Fdopen(t, "w")) == NULL) {
		warn("%s", tempname);
		goto out;
	}
	if (readonly && fchmod(t, 0400) == -1) {
		warn("%s", tempname);
		(void)rm(tempname);
		goto out;
	}
	if (size >= 0)
		while (--size >= 0 && (t = getc(fp)) != EOF)
			(void)putc(t, nf);
	else
		while ((t = getc(fp)) != EOF)
			(void)putc(t, nf);
	(void)fflush(nf);
	if (fstat(fileno(nf), &statb) < 0)
		modtime = 0;
	else
		modtime = statb.st_mtime;
	if (ferror(nf)) {
		(void)Fclose(nf);
		warnx("%s", tempname);
		(void)rm(tempname);
		nf = NULL;
		goto out;
	}
	if (Fclose(nf) < 0) {
		warn("%s", tempname);
		(void)rm(tempname);
		nf = NULL;
		goto out;
	}
	nf = NULL;
	if ((edit = value(type == 'e' ? "EDITOR" : "VISUAL")) == NULL)
		edit = type == 'e' ? _PATH_EX : _PATH_VI;
	if (run_command(edit, 0, -1, -1, tempname, NULL, NULL) < 0) {
		(void)rm(tempname);
		goto out;
	}
	/*
	 * If in read only mode or file unchanged, just remove the editor
	 * temporary and return.
	 */
	if (readonly) {
		(void)rm(tempname);
		goto out;
	}
	if (stat(tempname, &statb) < 0) {
		warn("%s", tempname);
		goto out;
	}
	if (modtime == statb.st_mtime) {
		(void)rm(tempname);
		goto out;
	}
	/*
	 * Now switch to new file.
	 */
	if ((nf = Fopen(tempname, "a+")) == NULL) {
		warn("%s", tempname);
		(void)rm(tempname);
		goto out;
	}
	(void)rm(tempname);
out:
	return (nf);
}
Exemplo n.º 9
0
int main(int argc, char *argv[]){
	char *t;
	int fd;
	char *tmp=NULL;
	struct bsdconv_instance *ins;
	FILE *inf=NULL, *otf=stdout;
	int inplace=0;
	int i;

	if(argc<2){
		fprintf(stderr, "Usage:\n\t %s conversion|-l [-i] [file] [...]\n\t\t-i:\tsave in-place\n\t\t-l:\tlist codecs\n", argv[0]);
		exit(1);
	}
	i=2;

	if(strcmp(argv[1],"-l")==0){
		list_modules();
		return 0;
	}

	if(argc>2) while(i<argc){
		if(strcmp(argv[i],"-i")==0)
			inplace=1;
		else if(strcmp(argv[i],"-l")==0)
			list_modules();
		else
			break;
		i+=1;
	}


#ifdef WIN32
	setmode(STDIN_FILENO, O_BINARY);
	setmode(STDOUT_FILENO, O_BINARY);
#endif

	ins=bsdconv_create(argv[1]);
	if(!ins){
		t=bsdconv_error();
		fprintf(stderr, "%s\n", t);
		free(t);
		exit(1);
	}

	if(i>=argc){
		bsdconv_file(ins, stdin, stdout, NULL);
	}else for(;i<argc;++i){
		if(inplace){
			inf=fopen(argv[i],"rb");
			if(inf==NULL){
				fprintf(stderr, "Failed opening file %s.\n", argv[i]);
				bsdconv_destroy(ins);
				exit(1);
			}
			tmp=malloc(strlen(argv[i])+8);
			strcpy(tmp, argv[i]);
			strcat(tmp, ".XXXXXX");
			if((fd=mkstemp(tmp))==-1){
				free(tmp);
				fprintf(stderr, "Failed creating temp file.\n");
				bsdconv_destroy(ins);
				exit(1);
			}
			otf=fdopen(fd, "wb");
			if(!otf){
				fprintf(stderr, "Unable to open output file for %s\n", argv[i]);
				bsdconv_destroy(ins);
				exit(1);
			}
#ifndef WIN32
			struct stat stat;
			fstat(fileno(inf), &stat);
			fchown(fileno(otf), stat.st_uid, stat.st_gid);
			fchmod(fileno(otf), stat.st_mode);
#endif
			bsdconv_file(ins, inf, otf, argv[i]);
			fclose(inf);
			fclose(otf);
			unlink(argv[i]);
			rename(tmp,argv[i]);
			free(tmp);

		}else{
			inf=fopen(argv[i],"rb");
			if(inf==NULL){
				fprintf(stderr, "Failed opening file %s.\n", argv[i]);
				bsdconv_destroy(ins);
				exit(1);
			}
			bsdconv_file(ins, inf, stdout, argv[i]);
			fclose(inf);
		}
	}
	bsdconv_destroy(ins);

	return 0;
}
Exemplo n.º 10
0
/**
 * Async HTTP callback
 */
static void
rspamd_map_common_http_callback (struct rspamd_map *map, struct rspamd_map_backend *bk,
		struct map_periodic_cbdata *periodic, gboolean check)
{
	struct http_map_data *data;
	struct http_callback_data *cbd;
	gchar tmpbuf[PATH_MAX];

	data = bk->data.hd;
	cbd = g_slice_alloc0 (sizeof (struct http_callback_data));

	rspamd_snprintf (tmpbuf, sizeof (tmpbuf),
			"%s" G_DIR_SEPARATOR_S "rspamd_map%d-XXXXXX",
			map->cfg->temp_dir, map->id);
	cbd->out_fd = mkstemp (tmpbuf);

	if (cbd->out_fd == -1) {
		msg_err_map ("cannot create tempfile: %s", strerror (errno));
		g_atomic_int_set (map->locked, 0);
		g_slice_free1 (sizeof (*cbd), cbd);
		periodic->errored = TRUE;
		rspamd_map_periodic_callback (-1, EV_TIMEOUT, periodic);

		return;
	}

	cbd->tmpfile = g_strdup (tmpbuf);
	cbd->ev_base = map->ev_base;
	cbd->map = map;
	cbd->data = data;
	cbd->fd = -1;
	cbd->check = check;
	cbd->periodic = periodic;
	MAP_RETAIN (periodic);
	cbd->bk = bk;
	MAP_RETAIN (bk);
	cbd->stage = map_resolve_host2;
	double_to_tv (map->cfg->map_timeout, &cbd->tv);
	REF_INIT_RETAIN (cbd, free_http_cbdata);

	msg_debug_map ("%s map data from %s", check ? "checking" : "reading",
			data->host);
	/* Send both A and AAAA requests */
	if (map->r->r) {
		if (rdns_make_request_full (map->r->r, rspamd_map_dns_callback, cbd,
				map->cfg->dns_timeout, map->cfg->dns_retransmits, 1,
				data->host, RDNS_REQUEST_A)) {
			MAP_RETAIN (cbd);
		}
		if (rdns_make_request_full (map->r->r, rspamd_map_dns_callback, cbd,
				map->cfg->dns_timeout, map->cfg->dns_retransmits, 1,
				data->host, RDNS_REQUEST_AAAA)) {
			MAP_RETAIN (cbd);
		}

		map->dtor = free_http_cbdata_dtor;
		map->dtor_data = cbd;
	}
	else {
		msg_warn_map ("cannot load map: DNS resolver is not initialized");
		cbd->periodic->errored = TRUE;
	}

	/* We don't need own ref as it is now ref counted by DNS handlers */
	MAP_RELEASE (cbd);
}
Exemplo n.º 11
0
/*
 * Add given variable with given value to file, overwriting any
 * previous occurrence.
 */
int
var_set(const char *fname, const char *variable, const char *value)
{
	FILE   *fp;
	FILE   *fout;
	char   *tmpname;
	int     fd;
	char   *line;
	size_t  len;
	size_t  varlen;
	Boolean done;
	struct stat st;

	varlen = strlen(variable);
	if (varlen == 0)
		return 0;

	fp = fopen(fname, "r");
	if (fp == NULL) {
		if (errno != ENOENT) {
			warn("var_set: can't open '%s' for reading", fname);
			return -1;
		}
		if (value == NULL)
			return 0; /* Nothing to do */
	}

	tmpname = xasprintf("%s.XXXXXX", fname);
	if ((fd = mkstemp(tmpname)) < 0) {
		free(tmpname);
		if (fp != NULL)
			fclose(fp);
		warn("var_set: can't open temp file for '%s' for writing",
		      fname);
		return -1;
	}
	if (chmod(tmpname, 0644) < 0) {
		close(fd);
		if (fp != NULL)
			fclose(fp);
		free(tmpname);
		warn("var_set: can't set permissions for temp file for '%s'",
		      fname);
		return -1;
	}
	if ((fout=fdopen(fd, "w")) == NULL) {
		close(fd);
		remove(tmpname);
		free(tmpname);
		if (fp != NULL)
			fclose(fp);
		warn("var_set: can't open temp file for '%s' for writing",
		      fname);
		return -1;
	}

	done = FALSE;

	if (fp) {
		while ((line = fgetln(fp, &len)) != (char *) NULL) {
			if (var_cmp(line, len, variable, varlen) == NULL)
				fprintf(fout, "%.*s", (int)len, line);
			else {
				if (!done && value) {
					var_print(fout, variable, value);
					done = TRUE;
				}
			}
		}
		(void) fclose(fp);
	}

	if (!done && value)
		var_print(fout, variable, value);

	if (fclose(fout) < 0) {
		free(tmpname);
		warn("var_set: write error for '%s'", fname);
		return -1;
	}

	if (stat(tmpname, &st) < 0) {
		free(tmpname);
		warn("var_set: cannot stat tempfile for '%s'", fname);
		return -1;
	}

	if (st.st_size == 0) {
		if (remove(tmpname) < 0) {
			free(tmpname);
			warn("var_set: cannot remove tempfile for '%s'",
			     fname);
			return -1;
		}
		free(tmpname);
		if (remove(fname) < 0) {
			warn("var_set: cannot remove '%s'", fname);
			return -1;
		}
		return 0;
	}

	if (rename(tmpname, fname) < 0) {
		free(tmpname);
		warn("var_set: cannot move tempfile to '%s'", fname);
		return -1;
	}
	free(tmpname);
	return 0;
}
Exemplo n.º 12
0
int
main(int argc, char **argv)
{
	struct quotause *qup, *protoprivs, *curprivs;
	long id, protoid;
	long long lim;
	int i, quotatype, range, tmpfd;
	uid_t startuid, enduid;
	u_int32_t *limp;
	char *protoname, *cp, *oldoptarg, ch;
	int eflag = 0, tflag = 0, pflag = 0;
	char *fspath = NULL;
	char buf[MAXLOGNAME];

	if (argc < 2)
		usage();
	if (getuid())
		errx(1, "permission denied");
	quotatype = USRQUOTA;
	protoprivs = NULL;
	curprivs = NULL;
	protoname = NULL;
	while ((ch = getopt(argc, argv, "ugtf:p:e:")) != -1) {
		switch(ch) {
		case 'f':
			fspath = optarg;
			break;
		case 'p':
			protoname = optarg;
			pflag++;
			break;
		case 'g':
			quotatype = GRPQUOTA;
			break;
		case 'u':
			quotatype = USRQUOTA;
			break;
		case 't':
			tflag++;
			break;
		case 'e':
			if ((qup = malloc(sizeof(*qup))) == NULL)
				errx(2, "out of memory");
			bzero(qup, sizeof(*qup));
			i = 0;
			oldoptarg = optarg;
			for (cp = optarg; (cp = strsep(&optarg, ":")) != NULL;
			    i++) {
				if (cp != oldoptarg)
					*(cp - 1) = ':';
				limp = NULL;
				switch (i) {
				case 0:
					strlcpy(qup->fsname, cp,
					    sizeof(qup->fsname));
					break;
				case 1:
					limp = &qup->dqblk.dqb_bsoftlimit;
					break;
				case 2:
					limp = &qup->dqblk.dqb_bhardlimit;
					break;
				case 3:
					limp = &qup->dqblk.dqb_isoftlimit;
					break;
				case 4:
					limp = &qup->dqblk.dqb_ihardlimit;
					break;
				default:
					warnx("incorrect quota specification: "
					    "%s", oldoptarg);
					usage();
					break; /* XXX: report an error */
				}
				if (limp != NULL) {
					lim = strtoll(cp, NULL, 10);
					if (lim < 0 || lim > UINT_MAX)
						errx(1, "invalid limit value: "
						    "%lld", lim);
					*limp = (u_int32_t)lim;
				}
			}
			qup->dqblk.dqb_bsoftlimit =
			    btodb((off_t)qup->dqblk.dqb_bsoftlimit * 1024);
			qup->dqblk.dqb_bhardlimit =
			    btodb((off_t)qup->dqblk.dqb_bhardlimit * 1024);
			if (protoprivs == NULL) {
				protoprivs = curprivs = qup;
			} else {
				curprivs->next = qup;
				curprivs = qup;
			}
			eflag++;
			pflag++;
			break;
		default:
			usage();
		}
	}
	argc -= optind;
	argv += optind;
	if (pflag) {
		if (protoprivs == NULL) {
			if ((protoid = getentry(protoname, quotatype)) == -1)
				exit(1);
			protoprivs = getprivs(protoid, quotatype, fspath);
			for (qup = protoprivs; qup; qup = qup->next) {
				qup->dqblk.dqb_btime = 0;
				qup->dqblk.dqb_itime = 0;
			}
		}
		for (; argc-- > 0; argv++) {
			if (strspn(*argv, "0123456789-") == strlen(*argv) &&
			    (cp = strchr(*argv, '-')) != NULL) {
				*cp++ = '\0';
				startuid = atoi(*argv);
				enduid = atoi(cp);
				if (enduid < startuid)
					errx(1,
	"ending uid (%d) must be >= starting uid (%d) when using uid ranges",
						enduid, startuid);
				range = 1;
			} else {
				startuid = enduid = 0;
				range = 0;
			}
			for ( ; startuid <= enduid; startuid++) {
				if (range)
					snprintf(buf, sizeof(buf), "%d",
					    startuid);
				else
					snprintf(buf, sizeof(buf), "%s",
						*argv);
				if ((id = getentry(buf, quotatype)) < 0)
					continue;
				if (eflag) {
					for (qup = protoprivs; qup;
					    qup = qup->next) {
						curprivs = getprivs(id,
						    quotatype, qup->fsname);
						if (curprivs == NULL)
							continue;
						strcpy(qup->qfname,
						    curprivs->qfname);
						strcpy(qup->fsname,
						    curprivs->fsname);
					}
				}
				putprivs(id, quotatype, protoprivs);						
			}
		}
		exit(0);
	}
	tmpfd = mkstemp(tmpfil);
	fchown(tmpfd, getuid(), getgid());
	if (tflag) {
		protoprivs = getprivs(0, quotatype, fspath);
		if (writetimes(protoprivs, tmpfd, quotatype) == 0)
			exit(1);
		if (editit(tmpfil) && readtimes(protoprivs, tmpfil))
			putprivs(0, quotatype, protoprivs);
		freeprivs(protoprivs);
		close(tmpfd);
		unlink(tmpfil);
		exit(0);
	}
	for ( ; argc > 0; argc--, argv++) {
		if ((id = getentry(*argv, quotatype)) == -1)
			continue;
		curprivs = getprivs(id, quotatype, fspath);
		if (writeprivs(curprivs, tmpfd, *argv, quotatype) == 0)
			continue;
		if (editit(tmpfil) && readprivs(curprivs, tmpfil))
			putprivs(id, quotatype, curprivs);
		freeprivs(curprivs);
	}
	close(tmpfd);
	unlink(tmpfil);
	exit(0);
}
Exemplo n.º 13
0
int
restoreText(struct butm_tapeInfo *tapeInfo,
	    struct rstTapeInfo *rstTapeInfoPtr,
	    struct structDumpHeader *nextHeader)
{
    char filename[64];
    afs_int32 nbytes;
    char *readBuffer = 0;
    afs_int32 readBlockSize;
    afs_int32 transferSize;
    struct structDumpHeader netItemHeader;
    int fid = -1;
    afs_int32 code = 0;

    udbClientTextP ctPtr = 0;
    afs_int32 textType;

    ctPtr = (udbClientTextP) malloc(sizeof(*ctPtr));
    if (!ctPtr)
	ERROR_EXIT(TC_NOMEMORY);

    /* determine the type of text block */
    switch (nextHeader->type) {
    case SD_TEXT_DUMPSCHEDULE:
	textType = TB_DUMPSCHEDULE;
	break;

    case SD_TEXT_VOLUMESET:
	textType = TB_VOLUMESET;
	break;

    case SD_TEXT_TAPEHOSTS:
	textType = TB_TAPEHOSTS;
	break;

    default:
	ErrorLog(0, rstTapeInfoPtr->taskId, TC_INTERNALERROR, 0,
		 "Unknown text block\n");
	ERROR_EXIT(TC_INTERNALERROR);
	break;
    }

    /* open the text file */
    sprintf(filename, "%s/bu_XXXXXX", gettmpdir());
#if defined (HAVE_MKSTEMP)
    fid = mkstemp(filename);
#else
    fid = open(mktemp(filename), O_RDWR | O_CREAT | O_EXCL, 0600);
#endif
    if (fid < 0) {
	ErrorLog(0, rstTapeInfoPtr->taskId, errno, 0,
		 "Can't open temporary text file: %s\n", filename);
	ERROR_EXIT(errno);
    }

    /* allocate buffer for text */
    readBlockSize = BUTM_BLKSIZE;
    readBuffer = (char *)malloc(readBlockSize);
    if (!readBuffer)
	ERROR_EXIT(TC_NOMEMORY);

    /* read the text into the temporary file */
    nbytes = nextHeader->size;
    while (nbytes > 0) {
	transferSize = (readBlockSize < nbytes) ? readBlockSize : nbytes;

	/* read it from the tape */
	code =
	    getTapeData(tapeInfo, rstTapeInfoPtr, readBuffer, transferSize);
	if (code)
	    ERROR_EXIT(code);

	/* write to the file */
	if (write(fid, readBuffer, transferSize) != transferSize) {
	    ErrorLog(0, rstTapeInfoPtr->taskId, errno, 0,
		     "Can't write temporary text file: %s\n", filename);
	    ERROR_EXIT(errno);
	}

	nbytes -= transferSize;
    }

    close(fid);
    fid = -1;
    code = saveTextFile(rstTapeInfoPtr->taskId, textType, filename);
    if (code)
	ERROR_EXIT(code);
    unlink(filename);

    /* get the next item-header */
    memset(nextHeader, 0, sizeof(*nextHeader));
    code =
	getTapeData(tapeInfo, rstTapeInfoPtr, &netItemHeader,
		    sizeof(netItemHeader));
    if (code)
	ERROR_EXIT(code);
    structDumpHeader_ntoh(&netItemHeader, nextHeader);

  error_exit:
    if (ctPtr)
	free(ctPtr);
    if (readBuffer)
	free(readBuffer);
    if (fid != -1) {
	close(fid);
	unlink(filename);
    }
    return (code);
}
Exemplo n.º 14
0
HB_FHANDLE hb_fsCreateTempEx( char * pszName, const char * pszDir, const char * pszPrefix, const char * pszExt, HB_FATTR ulAttr )
{
   /* less attemps */
   int iAttemptLeft = 99, iLen;
   HB_FHANDLE fd;

   do
   {
      pszName[ 0 ] = '\0';

      if( pszDir && pszDir[ 0 ] != '\0' )
      {
         hb_strncpy( pszName, pszDir, HB_PATH_MAX - 1 );
         iLen = ( int ) strlen( pszName );
         if( pszName[ iLen - 1 ] != HB_OS_PATH_DELIM_CHR &&
             iLen < HB_PATH_MAX - 1 )
         {
            pszName[ iLen ] = HB_OS_PATH_DELIM_CHR;
            pszName[ iLen + 1 ] = '\0';
         }
      }
      else
         hb_fsTempDir( pszName );

      if( pszPrefix )
         hb_strncat( pszName, pszPrefix, HB_PATH_MAX - 1 );

      iLen = ( int ) strlen( pszName );
      if( iLen > ( HB_PATH_MAX - 1 ) - 6 -
                 ( pszExt ? ( int ) strlen( pszExt ) : 0 ) )
      {
         fd = FS_ERROR;
         break;
      }

#if defined( HB_HAS_MKSTEMP )
      if( hb_setGetFileCase() != HB_SET_CASE_LOWER &&
          hb_setGetFileCase() != HB_SET_CASE_UPPER &&
          hb_setGetDirCase() != HB_SET_CASE_LOWER &&
          hb_setGetDirCase() != HB_SET_CASE_UPPER
#if ! defined( HB_HAS_MKSTEMPS )
          && ( pszExt == NULL || *pszExt == 0 )
#endif
        )
      {
         hb_vmUnlock();
         hb_strncat( pszName, "XXXXXX", HB_PATH_MAX - 1 );
#if defined( HB_HAS_MKSTEMPS )
         if( pszExt && *pszExt )
         {
            hb_strncat( pszName, pszExt, HB_PATH_MAX - 1 );
#if defined( HB_USE_LARGEFILE64 )
            fd = ( HB_FHANDLE ) mkstemps64( pszName, ( int ) strlen( pszExt ) );
#else
            fd = ( HB_FHANDLE ) mkstemps( pszName, ( int ) strlen( pszExt ) );
#endif
         }
         else
#endif
#if defined( HB_USE_LARGEFILE64 )
            fd = ( HB_FHANDLE ) mkstemp64( pszName );
#else
            fd = ( HB_FHANDLE ) mkstemp( pszName );
#endif
         hb_fsSetIOError( fd != ( HB_FHANDLE ) -1, 0 );
         hb_vmLock();
      }
      else
#endif /* HB_HAS_MKSTEMP */
      {
         int i, n;
         double d = hb_random_num(), x;

         for( i = 0; i < 6; i++ )
         {
            d = d * 36;
            n = ( int ) d;
            d = modf( d, &x );
            pszName[ iLen++ ] = ( char ) ( n + ( n > 9 ? 'a' - 10 : '0' ) );
         }
         pszName[ iLen ] = '\0';
         if( pszExt )
            hb_strncat( pszName, pszExt, HB_PATH_MAX - 1 );
         fd = hb_fsCreateEx( pszName, ulAttr, FO_EXCLUSIVE | FO_EXCL );
      }

      if( fd != ( HB_FHANDLE ) FS_ERROR )
         break;
   }
   while( --iAttemptLeft );

   return fd;
}
Exemplo n.º 15
0
/*
 * Parse edit command.  Returns 0 on success, -1 on error.
 */
int
eparse(const char *cmd, const char *left, const char *right)
{
	FILE *file;
	size_t nread;
	int fd;
	char *filename;
	char buf[BUFSIZ], *text;

	/* Skip whitespace. */
	while (isspace(*cmd))
		++cmd;

	text = NULL;
	switch (*cmd) {
	case '\0':
		/* Edit empty file. */
		break;

	case 'b':
		/* Both strings. */
		if (left == NULL)
			goto RIGHT;
		if (right == NULL)
			goto LEFT;

		/* Neither column is blank, so print both. */
		if (asprintf(&text, "%s\n%s\n", left, right) == -1)
			err(2, "could not allocate memory");
		break;

	case 'l':
LEFT:
		/* Skip if there is no left column. */
		if (left == NULL)
			break;

		if (asprintf(&text, "%s\n", left) == -1)
			err(2, "could not allocate memory");

		break;

	case 'r':
RIGHT:
		/* Skip if there is no right column. */
		if (right == NULL)
			break;

		if (asprintf(&text, "%s\n", right) == -1)
			err(2, "could not allocate memory");

		break;

	default:
		return (-1);
	}

	/* Create temp file. */
	if (asprintf(&filename, "%s/sdiff.XXXXXXXXXX", tmpdir) == -1)
		err(2, "asprintf");
	if ((fd = mkstemp(filename)) == -1)
		err(2, "mkstemp");
	if (text != NULL) {
		size_t len;
		ssize_t nwritten;

		len = strlen(text);
		if ((nwritten = write(fd, text, len)) == -1 ||
		    nwritten != len) {
			warn("error writing to temp file");
			cleanup(filename);
		}
	}
	close(fd);

	/* text is no longer used. */
	free(text);

	/* Edit temp file. */
	if (editit(filename) == -1) {
		warn("error editing %s", filename);
		cleanup(filename);
	}

	/* Open temporary file. */
	if (!(file = fopen(filename, "r"))) {
		warn("could not open edited file: %s", filename);
		cleanup(filename);
	}

	/* Copy temporary file contents to output file. */
	for (nread = sizeof(buf); nread == sizeof(buf);) {
		size_t nwritten;

		nread = fread(buf, sizeof(*buf), sizeof(buf), file);
		/* Test for error or end of file. */
		if (nread != sizeof(buf) &&
		    (ferror(file) || !feof(file))) {
			warnx("error reading edited file: %s", filename);
			cleanup(filename);
		}

		/*
		 * If we have nothing to read, break out of loop
		 * instead of writing nothing.
		 */
		if (!nread)
			break;

		/* Write data we just read. */
		nwritten = fwrite(buf, sizeof(*buf), nread, outfp);
		if (nwritten != nread) {
			warnx("error writing to output file");
			cleanup(filename);
		}
	}

	/* We've reached the end of the temporary file, so remove it. */
	if (unlink(filename))
		warn("could not delete: %s", filename);
	fclose(file);

	free(filename);

	return (0);
}
Exemplo n.º 16
0
int dbf_show_records (DBF *dbf)
{
  int i,err=0;
  double cmp;
  int len;
  ui32 position;
  CONDITION *p;
  
  char cmd[256];
  char tmpname [L_tmpnam]="/tmp/dbf2txt-XXXXXX";
  FILE *fp;
  
  /* Set var_id */
  for (p=dbf->condition;p;p=p->next)
  {
    for (i=0;i<dbf->NumberOfFields;i++)
    {
      if ((xstrcmpi (dbf->sub_header[i]->FieldName,p->var))==0)
      {
        p->var_id=i;
        break;
      }
    }
    if (i==dbf->NumberOfFields)
    {
      printf ("field \'%s\' not found in archive dbf\n",p->var);
      err=-1;
    }
  }
  if (err)
    return err;


  if ((mkstemp(tmpname))<0)
  {
    perror ("mkstemp");
    return -1;
  }
  if ((fp=fopen (tmpname,"w"))==NULL)
  {
    printf ("Cannot open `%s`\n",tmpname);
    perror ("");
    return -1;
  }
    
  /* Applying conditions */
  dbf->NumberOfRecords=0;
  for (i=1;i<=dbf->header->NumberOfRecords;i++)
  {
    _dbf_load_record (dbf->fp_in, dbf->header, dbf->record, i, dbf->header->LengthOfOneDataRecord);
    if (_dbf_isdelete(dbf->record)>0)
      continue;
    
    p=dbf->condition;
    
    while (p)
    {
      position=char2ui32(dbf->sub_header[p->var_id]->DisplacementOfFieldInRecord);
      len=LengthOfField(dbf->sub_header[p->var_id]);
      if (_dbf_isnumeric(dbf->sub_header[p->var_id]))
        cmp=(strtod(dbf->record+position,NULL) - strtod(p->val,NULL));
      else
        cmp=(double)strncmp (dbf->record+position,p->val,strlen(p->val));
    
      if ( (p->op_id==EQ && cmp==0) || (p->op_id==LT && cmp<0) || 
           (p->op_id==LE && cmp<=0) || (p->op_id==GT && cmp>0) || 
           (p->op_id==GE && cmp>=0) || (p->op_id==NE && cmp!=0) )
        p=p->next;     
      else
        break;
      
    }
    if (p==NULL)
    {
      dbf->NumberOfRecords++;
      dbf_push_record (dbf, i, fp);
    }
  }
  fclose (fp);
  
  if (dbf->NumberOfRecords==0)
  {
    printf ("Record not found!\n");
    return 0;
  }

  sprintf (cmd,"LC_COLLATE=C sort %s -k2",tmpname);
  fp=popen (cmd, "r");
 
  err=dbf_dump (dbf,fp,tmpname);

  return err;
        
}
/**
 * @test 
 */
void test_file_permissions(void)
{
	char filename[MAXPATHLEN] = "/tmp/permsXXXXXX";
	int	 fd;
	int ret;
	GError *gerr = NULL;
	
	g_log_set_always_fatal(G_LOG_FATAL_MASK);

	/* 1st test: non-existent file */
	g_assert_cmpint(chassis_filemode_check_full("/tmp/a_non_existent_file", CHASSIS_FILEMODE_SECURE_MASK, &gerr), ==, -1);
	g_assert_cmpint(gerr->code, ==, G_FILE_ERROR_NOENT);
	g_clear_error(&gerr);

	fd = mkstemp(filename);
	if (fd < 0) {
		g_critical("%s: mkstemp(%s) failed: %s (%d)",
				G_STRLOC,
				filename,
				g_strerror(errno), errno);
	}
	g_assert_cmpint(fd, >=, 0);

	/* 2nd test: too permissive */
	ret = chmod(filename, TOO_OPEN);
	if (ret < 0) {
		g_critical("%s: chmod(%s) failed: %s (%d)",
				G_STRLOC,
				filename,
				g_strerror(errno), errno);
	}
	g_assert_cmpint(ret, ==, 0);
	g_assert_cmpint(chassis_filemode_check_full(filename, CHASSIS_FILEMODE_SECURE_MASK, &gerr), ==, 1);
	g_assert_cmpint(gerr->code, ==, G_FILE_ERROR_PERM);
	g_clear_error(&gerr);

	/* 3rd test: OK */
	ret = chmod(filename, GOOD_PERMS);
	if (ret < 0) {
		g_critical("%s: chmod(%s) failed: %s (%d)",
				G_STRLOC,
				filename,
				g_strerror(errno), errno);
	}
	g_assert_cmpint(ret, ==, 0);
	g_assert_cmpint(chassis_filemode_check_full(filename, CHASSIS_FILEMODE_SECURE_MASK, &gerr), ==, 0);
	g_assert(gerr == NULL);

	/* 4th test: non-regular file */
	close(fd);
	remove(filename);
	ret = mkdir(filename, GOOD_PERMS);
	if (ret < 0) {
		g_critical("%s: mkdir(%s) failed: %s (%d)",
				G_STRLOC,
				filename,
				g_strerror(errno), errno);
	}
	g_assert_cmpint(ret, ==, 0);
	g_assert_cmpint(chassis_filemode_check_full(filename, CHASSIS_FILEMODE_SECURE_MASK, &gerr), ==, -1);
	g_assert_cmpint(gerr->code, ==, G_FILE_ERROR_INVAL);
	g_clear_error(&gerr);

	/* clean up */
	ret = rmdir(filename);
	if (ret < 0) {
		g_critical("%s: rmdir(%s) failed: %s (%d)",
				G_STRLOC,
				filename,
				g_strerror(errno), errno);
	}
	g_assert_cmpint(ret, ==, 0);

}
Exemplo n.º 18
0
/*
 * Terminate an editing session by attempting to write out the user's
 * file from the temporary.  Save any new stuff appended to the file.
 */
void
edstop(void)
{
	int gotcha, c;
	struct message *mp;
	FILE *obuf, *ibuf, *readstat;
	struct stat statb;
	char tempname[PATHSIZE];

	if (readonly)
		return;
	holdsigs();
	if (Tflag != NULL) {
		if ((readstat = Fopen(Tflag, "w")) == NULL)
			Tflag = NULL;
	}
	for (mp = &message[0], gotcha = 0; mp < &message[msgCount]; mp++) {
		if (mp->m_flag & MNEW) {
			mp->m_flag &= ~MNEW;
			mp->m_flag |= MSTATUS;
		}
		if (mp->m_flag & (MODIFY|MDELETED|MSTATUS))
			gotcha++;
		if (Tflag != NULL && (mp->m_flag & (MREAD|MDELETED)) != 0) {
			char *id;

			if ((id = hfield("article-id", mp)) != NULL)
				fprintf(readstat, "%s\n", id);
		}
	}
	if (Tflag != NULL)
		(void)Fclose(readstat);
	if (!gotcha || Tflag != NULL)
		goto done;
	ibuf = NULL;
	if (stat(mailname, &statb) >= 0 && statb.st_size > mailsize) {
		int fd;

		(void)snprintf(tempname, sizeof(tempname),
		    "%s/mbox.XXXXXXXXXX", tmpdir);
		if ((fd = mkstemp(tempname)) == -1 ||
		    (obuf = Fdopen(fd, "w")) == NULL) {
			warn("%s", tempname);
			relsesigs();
			reset(0);
		}
		if ((ibuf = Fopen(mailname, "r")) == NULL) {
			warn("%s", mailname);
			(void)Fclose(obuf);
			(void)rm(tempname);
			relsesigs();
			reset(0);
		}
		(void)fseeko(ibuf, mailsize, SEEK_SET);
		while ((c = getc(ibuf)) != EOF)
			(void)putc(c, obuf);
		(void)Fclose(ibuf);
		(void)Fclose(obuf);
		if ((ibuf = Fopen(tempname, "r")) == NULL) {
			warn("%s", tempname);
			(void)rm(tempname);
			relsesigs();
			reset(0);
		}
		(void)rm(tempname);
	}
	printf("\"%s\" ", mailname);
	(void)fflush(stdout);
	if ((obuf = Fopen(mailname, "r+")) == NULL) {
		warn("%s", mailname);
		relsesigs();
		reset(0);
	}
	trunc(obuf);
	c = 0;
	for (mp = &message[0]; mp < &message[msgCount]; mp++) {
		if ((mp->m_flag & MDELETED) != 0)
			continue;
		c++;
		if (sendmessage(mp, obuf, NULL, NULL) < 0) {
			warnx("%s", mailname);
			relsesigs();
			reset(0);
		}
	}
	gotcha = (c == 0 && ibuf == NULL);
	if (ibuf != NULL) {
		while ((c = getc(ibuf)) != EOF)
			(void)putc(c, obuf);
		(void)Fclose(ibuf);
	}
	(void)fflush(obuf);
	if (ferror(obuf)) {
		warn("%s", mailname);
		relsesigs();
		reset(0);
	}
	(void)Fclose(obuf);
	if (gotcha) {
		(void)rm(mailname);
		printf("removed\n");
	} else
		printf("complete\n");
	(void)fflush(stdout);

done:
	relsesigs();
}
Exemplo n.º 19
0
File create_temp_file(char *to, const char *dir, const char *prefix,
                      int mode __attribute__((unused)),
                      myf MyFlags __attribute__((unused)))
{
    File file= -1;
#ifdef __WIN__
    TCHAR path_buf[MAX_PATH-14];
#endif

    DBUG_ENTER("create_temp_file");
    DBUG_PRINT("enter", ("dir: %s, prefix: %s", dir, prefix));
#if defined (__WIN__)

    /*
      Use GetTempPath to determine path for temporary files.
      This is because the documentation for GetTempFileName
      has the following to say about this parameter:
      "If this parameter is NULL, the function fails."
    */
    if (!dir)
    {
        if(GetTempPath(sizeof(path_buf), path_buf) > 0)
            dir = path_buf;
    }
    /*
      Use GetTempFileName to generate a unique filename, create
      the file and release it's handle
       - uses up to the first three letters from prefix
    */
    if (GetTempFileName(dir, prefix, 0, to) == 0)
        DBUG_RETURN(-1);

    DBUG_PRINT("info", ("name: %s", to));

    /*
      Open the file without the "open only if file doesn't already exist"
      since the file has already been created by GetTempFileName
    */
    if ((file= my_open(to,  (mode & ~O_EXCL), MyFlags)) < 0)
    {
        /* Open failed, remove the file created by GetTempFileName */
        int tmp= my_errno;
        (void) my_delete(to, MYF(0));
        my_errno= tmp;
    }

#elif defined(HAVE_MKSTEMP)
    {
        char prefix_buff[30];
        uint pfx_len;
        File org_file;

        pfx_len= (uint) (strmov(strnmov(prefix_buff,
                                        prefix ? prefix : "tmp.",
                                        sizeof(prefix_buff)-7),"XXXXXX") -
                         prefix_buff);
        if (!dir && ! (dir =getenv("TMPDIR")))
            dir=DEFAULT_TMPDIR;
        if (strlen(dir)+ pfx_len > FN_REFLEN-2)
        {
            errno=my_errno= ENAMETOOLONG;
            DBUG_RETURN(file);
        }
        strmov(convert_dirname(to,dir,NullS),prefix_buff);
        org_file=mkstemp(to);
        if (mode & O_TEMPORARY)
            (void) my_delete(to, MYF(MY_WME | ME_NOINPUT));
        file=my_register_filename(org_file, to, FILE_BY_MKSTEMP,
                                  EE_CANTCREATEFILE, MyFlags);
        /* If we didn't manage to register the name, remove the temp file */
        if (org_file >= 0 && file < 0)
        {
            int tmp=my_errno;
            close(org_file);
            (void) my_delete(to, MYF(MY_WME | ME_NOINPUT));
            my_errno=tmp;
        }
    }
#elif defined(HAVE_TEMPNAM)
    {
        extern char **environ;

        char *res,**old_env,*temp_env[1];
        if (dir && !dir[0])
        {   /* Change empty string to current dir */
            to[0]= FN_CURLIB;
            to[1]= 0;
            dir=to;
        }

        old_env= (char**) environ;
        if (dir)
        {   /* Don't use TMPDIR if dir is given */
            environ=(const char**) temp_env;
            temp_env[0]=0;
        }

        if ((res=tempnam((char*) dir, (char*) prefix)))
        {
            strmake(to,res,FN_REFLEN-1);
            (*free)(res);
            file=my_create(to,0,
                           (int) (O_RDWR | O_BINARY | O_TRUNC | O_EXCL | O_NOFOLLOW |
                                  O_TEMPORARY | O_SHORT_LIVED),
                           MYF(MY_WME));

        }
        else
        {
            DBUG_PRINT("error",("Got error: %d from tempnam",errno));
        }

        environ=(const char**) old_env;
    }
#else
#error No implementation found for create_temp_file
#endif
    if (file >= 0)
        thread_safe_increment(my_tmp_file_created,&THR_LOCK_open);
    DBUG_RETURN(file);
}
Exemplo n.º 20
0
/*
 * Save all of the undetermined messages at the top of "mbox"
 * Save all untouched messages back in the system mailbox.
 * Remove the system mailbox, if none saved there.
 */
void
quit(void)
{
	int mcount, p, modify, autohold, anystat, holdbit, nohold;
	FILE *ibuf, *obuf, *fbuf, *rbuf, *readstat, *abuf;
	struct message *mp;
	int c, fd;
	struct stat minfo;
	char *mbox, tempname[PATHSIZE];

	/*
	 * If we are read only, we can't do anything,
	 * so just return quickly.
	 */
	if (readonly)
		return;
	/*
	 * If editing (not reading system mail box), then do the work
	 * in edstop()
	 */
	if (edit) {
		edstop();
		return;
	}

	/*
	 * See if there any messages to save in mbox.  If no, we
	 * can save copying mbox to /tmp and back.
	 *
	 * Check also to see if any files need to be preserved.
	 * Delete all untouched messages to keep them out of mbox.
	 * If all the messages are to be preserved, just exit with
	 * a message.
	 */

	fbuf = Fopen(mailname, "r");
	if (fbuf == NULL)
		goto newmail;
	(void)flock(fileno(fbuf), LOCK_EX);
	rbuf = NULL;
	if (fstat(fileno(fbuf), &minfo) >= 0 && minfo.st_size > mailsize) {
		printf("New mail has arrived.\n");
		(void)snprintf(tempname, sizeof(tempname),
		    "%s/mail.RqXXXXXXXXXX", tmpdir);
		if ((fd = mkstemp(tempname)) == -1 ||
		    (rbuf = Fdopen(fd, "w")) == NULL)
			goto newmail;
#ifdef APPEND
		(void)fseeko(fbuf, mailsize, SEEK_SET);
		while ((c = getc(fbuf)) != EOF)
			(void)putc(c, rbuf);
#else
		p = minfo.st_size - mailsize;
		while (p-- > 0) {
			c = getc(fbuf);
			if (c == EOF)
				goto newmail;
			(void)putc(c, rbuf);
		}
#endif
		(void)Fclose(rbuf);
		if ((rbuf = Fopen(tempname, "r")) == NULL)
			goto newmail;
		(void)rm(tempname);
	}

	/*
	 * Adjust the message flags in each message.
	 */

	anystat = 0;
	autohold = value("hold") != NULL;
	holdbit = autohold ? MPRESERVE : MBOX;
	nohold = MBOX|MSAVED|MDELETED|MPRESERVE;
	if (value("keepsave") != NULL)
		nohold &= ~MSAVED;
	for (mp = &message[0]; mp < &message[msgCount]; mp++) {
		if (mp->m_flag & MNEW) {
			mp->m_flag &= ~MNEW;
			mp->m_flag |= MSTATUS;
		}
		if (mp->m_flag & MSTATUS)
			anystat++;
		if ((mp->m_flag & MTOUCH) == 0)
			mp->m_flag |= MPRESERVE;
		if ((mp->m_flag & nohold) == 0)
			mp->m_flag |= holdbit;
	}
	modify = 0;
	if (Tflag != NULL) {
		if ((readstat = Fopen(Tflag, "w")) == NULL)
			Tflag = NULL;
	}
	for (c = 0, p = 0, mp = &message[0]; mp < &message[msgCount]; mp++) {
		if (mp->m_flag & MBOX)
			c++;
		if (mp->m_flag & MPRESERVE)
			p++;
		if (mp->m_flag & MODIFY)
			modify++;
		if (Tflag != NULL && (mp->m_flag & (MREAD|MDELETED)) != 0) {
			char *id;

			if ((id = hfield("article-id", mp)) != NULL)
				fprintf(readstat, "%s\n", id);
		}
	}
	if (Tflag != NULL)
		(void)Fclose(readstat);
	if (p == msgCount && !modify && !anystat) {
		printf("Held %d message%s in %s\n",
			p, p == 1 ? "" : "s", mailname);
		(void)Fclose(fbuf);
		return;
	}
	if (c == 0) {
		if (p != 0) {
			writeback(rbuf);
			(void)Fclose(fbuf);
			return;
		}
		goto cream;
	}

	/*
	 * Create another temporary file and copy user's mbox file
	 * darin.  If there is no mbox, copy nothing.
	 * If he has specified "append" don't copy his mailbox,
	 * just copy saveable entries at the end.
	 */

	mbox = expand("&");
	mcount = c;
	if (value("append") == NULL) {
		(void)snprintf(tempname, sizeof(tempname),
		    "%s/mail.RmXXXXXXXXXX", tmpdir);
		if ((fd = mkstemp(tempname)) == -1 ||
		    (obuf = Fdopen(fd, "w")) == NULL) {
			warn("%s", tempname);
			(void)Fclose(fbuf);
			return;
		}
		if ((ibuf = Fopen(tempname, "r")) == NULL) {
			warn("%s", tempname);
			(void)rm(tempname);
			(void)Fclose(obuf);
			(void)Fclose(fbuf);
			return;
		}
		(void)rm(tempname);
		if ((abuf = Fopen(mbox, "r")) != NULL) {
			while ((c = getc(abuf)) != EOF)
				(void)putc(c, obuf);
			(void)Fclose(abuf);
		}
		if (ferror(obuf)) {
			warnx("%s", tempname);
			(void)Fclose(ibuf);
			(void)Fclose(obuf);
			(void)Fclose(fbuf);
			return;
		}
		(void)Fclose(obuf);
		(void)close(open(mbox, O_CREAT | O_TRUNC | O_WRONLY, 0600));
		if ((obuf = Fopen(mbox, "r+")) == NULL) {
			warn("%s", mbox);
			(void)Fclose(ibuf);
			(void)Fclose(fbuf);
			return;
		}
	}
	if (value("append") != NULL) {
		if ((obuf = Fopen(mbox, "a")) == NULL) {
			warn("%s", mbox);
			(void)Fclose(fbuf);
			return;
		}
		(void)fchmod(fileno(obuf), 0600);
	}
	for (mp = &message[0]; mp < &message[msgCount]; mp++)
		if (mp->m_flag & MBOX)
			if (sendmessage(mp, obuf, saveignore, NULL) < 0) {
				warnx("%s", mbox);
				(void)Fclose(ibuf);
				(void)Fclose(obuf);
				(void)Fclose(fbuf);
				return;
			}

	/*
	 * Copy the user's old mbox contents back
	 * to the end of the stuff we just saved.
	 * If we are appending, this is unnecessary.
	 */

	if (value("append") == NULL) {
		rewind(ibuf);
		c = getc(ibuf);
		while (c != EOF) {
			(void)putc(c, obuf);
			if (ferror(obuf))
				break;
			c = getc(ibuf);
		}
		(void)Fclose(ibuf);
	}
	(void)fflush(obuf);
	trunc(obuf);
	if (ferror(obuf)) {
		warn("%s", mbox);
		(void)Fclose(obuf);
		(void)Fclose(fbuf);
		return;
	}
	(void)Fclose(obuf);
	if (mcount == 1)
		printf("Saved 1 message in mbox\n");
	else
		printf("Saved %d messages in mbox\n", mcount);

	/*
	 * Now we are ready to copy back preserved files to
	 * the system mailbox, if any were requested.
	 */

	if (p != 0) {
		writeback(rbuf);
		(void)Fclose(fbuf);
		return;
	}

	/*
	 * Finally, remove his /var/mail file.
	 * If new mail has arrived, copy it back.
	 */

cream:
	if (rbuf != NULL) {
		abuf = Fopen(mailname, "r+");
		if (abuf == NULL)
			goto newmail;
		while ((c = getc(rbuf)) != EOF)
			(void)putc(c, abuf);
		(void)Fclose(rbuf);
		trunc(abuf);
		(void)Fclose(abuf);
		alter(mailname);
		(void)Fclose(fbuf);
		return;
	}
	demail();
	(void)Fclose(fbuf);
	return;

newmail:
	printf("Thou hast new mail.\n");
	if (fbuf != NULL)
		(void)Fclose(fbuf);
}
Exemplo n.º 21
0
static void
gvinum_create(int argc, char * const *argv)
{
	struct gctl_req *req;
	struct gv_drive *d;
	struct gv_plex *p;
	struct gv_sd *s;
	struct gv_volume *v;
	FILE *tmp;
	int drives, errors, fd, flags, i, line, plexes, plex_in_volume;
	int sd_in_plex, status, subdisks, tokens, undeffd, volumes;
	const char *errstr;
	char buf[BUFSIZ], buf1[BUFSIZ], commandline[BUFSIZ], *sdname;
	const char *ed;
	char original[BUFSIZ], tmpfile[20], *token[GV_MAXARGS];
	char plex[GV_MAXPLEXNAME], volume[GV_MAXVOLNAME];

	tmp = NULL;
	flags = 0;
	for (i = 1; i < argc; i++) {
		/* Force flag used to ignore already created drives. */
		if (!strcmp(argv[i], "-f")) {
			flags |= GV_FLAG_F;
		/* Else it must be a file. */
		} else {
			if ((tmp = fopen(argv[i], "r")) == NULL) {
				warn("can't open '%s' for reading", argv[i]);
				return;
			}
		}	
	}

	/* We didn't get a file. */
	if (tmp == NULL) {
		snprintf(tmpfile, sizeof(tmpfile), "/tmp/gvinum.XXXXXX");
		
		if ((fd = mkstemp(tmpfile)) == -1) {
			warn("temporary file not accessible");
			return;
		}
		if ((tmp = fdopen(fd, "w")) == NULL) {
			warn("can't open '%s' for writing", tmpfile);
			return;
		}
		printconfig(tmp, "# ");
		fclose(tmp);
		
		ed = getenv("EDITOR");
		if (ed == NULL)
			ed = _PATH_VI;
		
		snprintf(commandline, sizeof(commandline), "%s %s", ed,
		    tmpfile);
		status = system(commandline);
		if (status != 0) {
			warn("couldn't exec %s; status: %d", ed, status);
			return;
		}
		
		if ((tmp = fopen(tmpfile, "r")) == NULL) {
			warn("can't open '%s' for reading", tmpfile);
			return;
		}
	}

	req = gctl_get_handle();
	gctl_ro_param(req, "class", -1, "VINUM");
	gctl_ro_param(req, "verb", -1, "create");
	gctl_ro_param(req, "flags", sizeof(int), &flags);

	drives = volumes = plexes = subdisks = 0;
	plex_in_volume = sd_in_plex = undeffd = 0;
	plex[0] = '\0';
	errors = 0;
	line = 1;
	while ((fgets(buf, BUFSIZ, tmp)) != NULL) {

		/* Skip empty lines and comments. */
		if (*buf == '\0' || *buf == '#') {
			line++;
			continue;
		}

		/* Kill off the newline. */
		buf[strlen(buf) - 1] = '\0';

		/*
		 * Copy the original input line in case we need it for error
		 * output.
		 */
		strlcpy(original, buf, sizeof(original));

		tokens = gv_tokenize(buf, token, GV_MAXARGS);
		if (tokens <= 0) {
			line++;
			continue;
		}

		/* Volume definition. */
		if (!strcmp(token[0], "volume")) {
			v = gv_new_volume(tokens, token);
			if (v == NULL) {
				warnx("line %d: invalid volume definition",
				    line);
				warnx("line %d: '%s'", line, original);
				errors++;
				line++;
				continue;
			}

			/* Reset plex count for this volume. */
			plex_in_volume = 0;

			/*
			 * Set default volume name for following plex
			 * definitions.
			 */
			strlcpy(volume, v->name, sizeof(volume));

			snprintf(buf1, sizeof(buf1), "volume%d", volumes);
			gctl_ro_param(req, buf1, sizeof(*v), v);
			volumes++;

		/* Plex definition. */
		} else if (!strcmp(token[0], "plex")) {
			p = gv_new_plex(tokens, token);
			if (p == NULL) {
				warnx("line %d: invalid plex definition", line);
				warnx("line %d: '%s'", line, original);
				errors++;
				line++;
				continue;
			}

			/* Reset subdisk count for this plex. */
			sd_in_plex = 0;

			/* Default name. */
			if (strlen(p->name) == 0) {
				snprintf(p->name, sizeof(p->name), "%s.p%d",
				    volume, plex_in_volume++);
			}

			/* Default volume. */
			if (strlen(p->volume) == 0) {
				snprintf(p->volume, sizeof(p->volume), "%s",
				    volume);
			}

			/*
			 * Set default plex name for following subdisk
			 * definitions.
			 */
			strlcpy(plex, p->name, sizeof(plex));

			snprintf(buf1, sizeof(buf1), "plex%d", plexes);
			gctl_ro_param(req, buf1, sizeof(*p), p);
			plexes++;

		/* Subdisk definition. */
		} else if (!strcmp(token[0], "sd")) {
			s = gv_new_sd(tokens, token);
			if (s == NULL) {
				warnx("line %d: invalid subdisk "
				    "definition:", line);
				warnx("line %d: '%s'", line, original);
				errors++;
				line++;
				continue;
			}

			/* Default name. */
			if (strlen(s->name) == 0) {
				if (strlen(plex) == 0) {
					sdname = find_name("gvinumsubdisk.p",
					    GV_TYPE_SD, GV_MAXSDNAME);
					snprintf(s->name, sizeof(s->name),
					    "%s.s%d", sdname, undeffd++);
					free(sdname);
				} else {
					snprintf(s->name, sizeof(s->name),
					    "%s.s%d",plex, sd_in_plex++);
				}
			}

			/* Default plex. */
			if (strlen(s->plex) == 0)
				snprintf(s->plex, sizeof(s->plex), "%s", plex);

			snprintf(buf1, sizeof(buf1), "sd%d", subdisks);
			gctl_ro_param(req, buf1, sizeof(*s), s);
			subdisks++;

		/* Subdisk definition. */
		} else if (!strcmp(token[0], "drive")) {
			d = gv_new_drive(tokens, token);
			if (d == NULL) {
				warnx("line %d: invalid drive definition:",
				    line);
				warnx("line %d: '%s'", line, original);
				errors++;
				line++;
				continue;
			}

			snprintf(buf1, sizeof(buf1), "drive%d", drives);
			gctl_ro_param(req, buf1, sizeof(*d), d);
			drives++;

		/* Everything else is bogus. */
		} else {
			warnx("line %d: invalid definition:", line);
			warnx("line %d: '%s'", line, original);
			errors++;
		}
		line++;
	}

	fclose(tmp);
	unlink(tmpfile);

	if (!errors && (volumes || plexes || subdisks || drives)) {
		gctl_ro_param(req, "volumes", sizeof(int), &volumes);
		gctl_ro_param(req, "plexes", sizeof(int), &plexes);
		gctl_ro_param(req, "subdisks", sizeof(int), &subdisks);
		gctl_ro_param(req, "drives", sizeof(int), &drives);
		errstr = gctl_issue(req);
		if (errstr != NULL)
			warnx("create failed: %s", errstr);
	}
	gctl_free(req);
}
Exemplo n.º 22
0
int f_mysql_speed(ARG7) {

    char temp_pathname[STRING_SIZE];
    char sql[1500];
    char server[100];
    char user[100];
    char password[100]; 
    char database[100];
    char table[100];
    MYSQL_RES *res;
    MYSQL_ROW row;

    char name[100], desc[100], unit[100], level_buf[100];
    int year, month, day, hour, minute, second;
	
    char vt[20],rt[20];
//    unsigned char *p;
   		
    int i,j;
    double longitude,latitude,value;

    char new_level[50];
    char new_name[50];
    char conv[50];
    char precision[10];
    char last;
    char param[50];
    int ctr;
    int level;
    unsigned int load_local_infile;

    struct local_struct {
        MYSQL *conn;
        FILE *temp_fileptr;
        unsigned int npts;
        char *rows[MAX_NXNY];
	char has_value[MAX_NXNY];
        char *params;
        unsigned int isset;
        unsigned int wlon;
        unsigned int remove_unlikely;
        char runtime[20], validtime[20];
	int last_GDS_change_no;
    };
    struct local_struct *save;

    strcpy(server,arg1);
    strcpy(user,arg2);
    strcpy(password,arg3);
    strcpy(database,arg4);
    strcpy(table,arg5);

    /* initialization phase */

    if (mode == -1) {
        decode = latlon = 1;
        
	*local = save = (struct local_struct *) malloc( sizeof(struct local_struct));
	if (save == NULL) fatal_error("mysql_speed memory allocation ","");

        for (i = 0; i < MAX_NXNY; i++) {
	    save->rows[i] = NULL;
	    save->has_value[i] = 0;
	}
	save->last_GDS_change_no = 0;
	save->conn = mysql_init(NULL);
	save->temp_fileptr= NULL;
	save->params = (char *)  malloc(1500*sizeof(char));
	sprintf(save->params,"%s","");
	save->isset = 0;
	save->runtime[0] = 0;
	save->validtime[0] = 0;
	load_local_infile = 1;		// 1 = LOAD LOCAL INFILE,  0 = do not LOAD LOCAL INFILE

	if (sscanf(arg6,"%d", &save->wlon) != 1) {
            fatal_error("Argument 6, use western longitudes, has to be 0 or 1, error parsing %s", arg6);
        }
        if (sscanf(arg7,"%d", &save->remove_unlikely) != 1) {
            fatal_error("Argument 7, remove unlikely values, has to be 0 or 1, error parsing %s", arg7);
        }
	
	/* Set options for database */
	mysql_options(save->conn,MYSQL_OPT_LOCAL_INFILE, (char *) &load_local_infile);

	/* Connect to database */
	if (!mysql_real_connect(save->conn, server, user, password, database, 0, NULL, 0)) {
	   fatal_error("f_mysql_speed: could not connect to %s", mysql_error(save->conn));
	} 
	return 0;
    }

    /* cleanup phase */

    if (mode == -2) {
    	save = (struct local_struct *) *local;
    	
    	strcpy(temp_pathname, "/tmp/wgrib2_mysqlXXXXXX");
    	if ( -1 == (load_local_infile = mkstemp(temp_pathname)) ) {
	    fatal_error("f_mysql_speed: error making temporary filename","");
	}
	if ( !(save->temp_fileptr = fdopen(load_local_infile, "w")) ) {
	    fatal_error("f_mysql_speed: error making temporary filename","");
	}

    	fprintf(stdout, "Columns to insert: rt,vt,lat,lon%s\n", save->params);
    	fprintf(save->temp_fileptr,"rt,vt,lat,lon%s\n",save->params);
    	for (j = 0; j < save->npts; j++) {
	    if (save->has_value[j] == 1) fprintf(save->temp_fileptr,"%s\n",save->rows[j]);
	}
	fflush(save->temp_fileptr);
	sprintf(sql,"LOAD DATA LOCAL INFILE '%s' INTO TABLE %s FIELDS TERMINATED BY ',' ENCLOSED BY '\"' LINES TERMINATED BY '\\n' IGNORE 1 LINES (rt,vt,lat,lon%s)",temp_pathname,table,save->params);
	printf("Inserting into database, table=%s \n",table);
	printf("%s\n",sql);
	/* send SQL query */
	if (mysql_query(save->conn, sql)) {	
	    fatal_error("f_mysql_speed: connection error %s", mysql_error(save->conn));
	}
	fclose(save->temp_fileptr);
	remove(temp_pathname);
    	mysql_close(save->conn);
    	return 0;
    }

    /* processing phase */

    save = (struct local_struct *) *local;
  	
//    if (new_GDS && save->isset == 0 ) {
    if ((save->last_GDS_change_no != GDS_change_no) && save->isset == 0 ) {
  	//save->npts = GB2_Sec3_npts(sec);
  	save->npts = ndata;
  	if (ndata > MAX_NXNY) fatal_error_i("f_mysql_speed: MAX_NXNY exceeded %d", MAX_NXNY);

	for (i = 0; i < ndata; i++) {
	    if (save->rows[i] == NULL) {
		save->rows[i] = (char *)  malloc(1500*sizeof(char));
		if (save->rows[i] == NULL) fatal_error("f_mysql_speed: memory allocation problem","");
	    }
	    save->rows[i][0] = '\0';
	}

	save->isset = 1;
//    } else if (new_GDS) {
    } else if (save->last_GDS_change_no != GDS_change_no) {
	fatal_error("f_mysql_speed, grid definition has to be the same for all fields","");
   }
   save->last_GDS_change_no = GDS_change_no;
 
    /*Collect runtime and validtime into vt and rt*/

    reftime(sec, &year, &month, &day, &hour, &minute, &second);
//  p = sec[1];
//  sprintf(rt, "%4.4d-%2.2d-%2.2d %2.2d:%2.2d:%2.2d", (p[12]<<8)+p[13], p[14],p[15],p[16],p[17],p[18]);
    sprintf(rt, "%4.4d-%2.2d-%2.2d %2.2d:%2.2d:%2.2d", year,month,day,hour,minute,second);

    if (verftime(sec, &year, &month, &day, &hour, &minute, &second) == 0) {
        sprintf(vt,"%4.4d-%2.2d-%2.2d %2.2d:%2.2d:%2.2d", year,month,day,hour,minute,second);
    }
    /*Check that runtimes are equal and validtimes are equal*/
    if (save->runtime[0] != 0 && strcmp(save->runtime,rt) != 0) {
	fprintf(stderr, "Error, runtime has to be equal for all fields\n");
    }
    strcpy(save->runtime,rt);

    if (save->validtime[0] != 0 && strcmp(save->validtime,vt) != 0) {
	fprintf(stderr, "Error, validtime has to be equal for all fields\n");
    }
    strcpy(save->validtime,vt);
	
    /*Get levels, parameter name, description and unit*/
    // f_lev(mode, sec, data, ndata, level_buf, local);
    f_lev(call_ARG0(level_buf, NULL));
    //if (ndata != save->npts && save->npts>0) fprintf(stderr,"ERROR: fields do not contain equally many gridpoints, %d , %d \n",save->npts,ndata);
 	   
    if (strcmp(level_buf, "reserved") == 0) return(0);
    getName(sec, mode, NULL, name, desc, unit);
    fprintf(stderr,"Start processing of %s at %s, runtime=%s, validtime=%s \n", name, level_buf,rt,vt);

    ctr = GB2_Center(sec);

    sprintf(sql,"select * from wgrib2_parameter_mapping where center_id=%d and wgrib_param_name='%s' and wgrib_param_levelname='%s'", ctr, name, level_buf);
    fprintf(stderr,"SQL: %s\n", sql);
    if (mysql_query(save->conn, sql)) {	
	fatal_error("f_mysql_speed: mysql error %s", mysql_error(save->conn));
    }
    sprintf(new_level,"%s", "None");
    sprintf(conv,"%s", "None");
    sprintf(precision, "%s", "2");
    printf("\nCenter_id: %d \n", ctr);
    res = mysql_use_result(save->conn);
    while ( (row = mysql_fetch_row(res) ) != NULL) {
	printf("our_name: %s \n", row[3]);
	sprintf(new_name,"%s", row[3]);
	sprintf(new_level,"%s", row[4]);
	sprintf(conv,"%s", row[5]);
	sprintf(precision, "%s", row[6]);
    }

    printf("val_precision: %s \n", precision);
    printf("conversion: %s \n", conv);
    printf("our_levelname: %s \n", new_level);
	
    if (strcmp(new_level,"None") != 0) {
	fprintf(stderr,"Sets level %s as level %s\n", level_buf, new_level);
	sprintf(param, "%s_%s", new_name, new_level);
    } else {
	if (strcmp(level_buf,"surface") == 0) {
	    sprintf(param, "%s_0", name);
	} else {		
	    sscanf(level_buf,"%d %s", &level, &last);
 	    sprintf(param, "%s_%d", name, level);
	}
    }
	
    mysql_free_result(res);

    strcat(save->params,",");
    strcat(save->params,param);
	
    fprintf(stderr,"Gridpoints in data: %d\n", ndata);
    fprintf(stderr, "Gridpoints for insert: %d\n", save->npts);

    fprintf(stderr, "Remove unlikely: %d\n", save->remove_unlikely);
    fprintf(stderr, "Western longitudes: %d\n", save->wlon);

    for (j = 0; j < ndata; j++) {
	longitude = lon[j];
	if (longitude > 180 && save->wlon==1) longitude-=360;
	latitude = lat[j];
	value = data[j];
	if (save->remove_unlikely == 1 && value>0 && value<10e-8) value=0; 			
	if (save->remove_unlikely == 1 && (strcmp(name,"APCP")==0 || strcmp(name,"ASNOW")==0 || strcmp(name,"ACPCP")==0 ) && value==1) value=0;
	value = convunit(value, conv);
	if (strlen(save->rows[j]) < 2) 	{
	    if (!UNDEFINED_VAL(data[j])) {
		save->has_value[j] = 1;
		sprintf(save->rows[j],"\"%s\",\"%s\",%g,%g,%lg",rt,vt,latitude,longitude,value);
	    } else {
		sprintf(save->rows[j],"\"%s\",\"%s\",%g,%g,NULL",rt,vt,latitude,longitude);
	    }
	} else {
	    if (!UNDEFINED_VAL(data[j])) {
		save->has_value[j] = 1;
		sprintf(sql,",%lg",value);
	    } else {
		sprintf(sql,",NULL");
	    }
	    strcat(save->rows[j],sql);
	}

    }
    return 0;
}
Exemplo n.º 23
0
static storage_status_t xml_save( irc_t *irc, int overwrite )
{
	char path[512], *path2, *pass_buf = NULL;
	set_t *set;
	account_t *acc;
	int fd;
	md5_byte_t pass_md5[21];
	md5_state_t md5_state;
	GSList *l;
	
	path2 = g_strdup( irc->user->nick );
	nick_lc( path2 );
	g_snprintf( path, sizeof( path ) - 2, "%s%s%s", global.conf->configdir, path2, ".xml" );
	g_free( path2 );
	
	if( !overwrite && g_access( path, F_OK ) == 0 )
		return STORAGE_ALREADY_EXISTS;
	
	strcat( path, ".XXXXXX" );
	if( ( fd = mkstemp( path ) ) < 0 )
	{
		irc_usermsg( irc, "Error while opening configuration file." );
		return STORAGE_OTHER_ERROR;
	}
	
	/* Generate a salted md5sum of the password. Use 5 bytes for the salt
	   (to prevent dictionary lookups of passwords) to end up with a 21-
	   byte password hash, more convenient for base64 encoding. */
	random_bytes( pass_md5 + 16, 5 );
	md5_init( &md5_state );
	md5_append( &md5_state, (md5_byte_t*) irc->password, strlen( irc->password ) );
	md5_append( &md5_state, pass_md5 + 16, 5 ); /* Add the salt. */
	md5_finish( &md5_state, pass_md5 );
	/* Save the hash in base64-encoded form. */
	pass_buf = base64_encode( pass_md5, 21 );
	
	if( !xml_printf( fd, 0, "<user nick=\"%s\" password=\"%s\" version=\"%d\">\n", irc->user->nick, pass_buf, XML_FORMAT_VERSION ) )
		goto write_error;
	
	g_free( pass_buf );
	
	for( set = irc->b->set; set; set = set->next )
		if( set->value && !( set->flags & SET_NOSAVE ) )
			if( !xml_printf( fd, 1, "<setting name=\"%s\">%s</setting>\n", set->key, set->value ) )
				goto write_error;
	
	for( acc = irc->b->accounts; acc; acc = acc->next )
	{
		unsigned char *pass_cr;
		char *pass_b64;
		int pass_len;
		
		pass_len = arc_encode( acc->pass, strlen( acc->pass ), (unsigned char**) &pass_cr, irc->password, 12 );
		pass_b64 = base64_encode( pass_cr, pass_len );
		g_free( pass_cr );
		
		if( !xml_printf( fd, 1, "<account protocol=\"%s\" handle=\"%s\" password=\"%s\" "
		                        "autoconnect=\"%d\" tag=\"%s\"", acc->prpl->name, acc->user,
		                        pass_b64, acc->auto_connect, acc->tag ) )
		{
			g_free( pass_b64 );
			goto write_error;
		}
		g_free( pass_b64 );
		
		if( acc->server && acc->server[0] && !xml_printf( fd, 0, " server=\"%s\"", acc->server ) )
			goto write_error;
		if( !xml_printf( fd, 0, ">\n" ) )
			goto write_error;
		
		for( set = acc->set; set; set = set->next )
			if( set->value && !( set->flags & ACC_SET_NOSAVE ) )
				if( !xml_printf( fd, 2, "<setting name=\"%s\">%s</setting>\n", set->key, set->value ) )
					goto write_error;
		
		/* This probably looks pretty strange. g_hash_table_foreach
		   is quite a PITA already (but it can't get much better in
		   C without using #define, I'm afraid), and since it
		   doesn't seem to be possible to abort the foreach on write
		   errors, so instead let's use the _find function and
		   return TRUE on write errors. Which means, if we found
		   something, there was an error. :-) */
		if( g_hash_table_find( acc->nicks, xml_save_nick, & fd ) )
			goto write_error;
		
		if( !xml_printf( fd, 1, "</account>\n" ) )
			goto write_error;
	}
	
	for( l = irc->channels; l; l = l->next )
	{
		irc_channel_t *ic = l->data;
		
		if( ic->flags & IRC_CHANNEL_TEMP )
			continue;
		
		if( !xml_printf( fd, 1, "<channel name=\"%s\" type=\"%s\">\n",
		                 ic->name, set_getstr( &ic->set, "type" ) ) )
			goto write_error;
		
		for( set = ic->set; set; set = set->next )
			if( set->value && strcmp( set->key, "type" ) != 0 )
				if( !xml_printf( fd, 2, "<setting name=\"%s\">%s</setting>\n", set->key, set->value ) )
					goto write_error;
		
		if( !xml_printf( fd, 1, "</channel>\n" ) )
			goto write_error;
	}
	
	if( !xml_printf( fd, 0, "</user>\n" ) )
		goto write_error;
	
	fsync( fd );
	close( fd );
	
	path2 = g_strndup( path, strlen( path ) - 7 );
	if( rename( path, path2 ) != 0 )
	{
		irc_usermsg( irc, "Error while renaming temporary configuration file." );
		
		g_free( path2 );
		unlink( path );
		
		return STORAGE_OTHER_ERROR;
	}
	
	g_free( path2 );
	
	return STORAGE_OK;

write_error:
	g_free( pass_buf );
	
	irc_usermsg( irc, "Write error. Disk full?" );
	close( fd );
	
	return STORAGE_OTHER_ERROR;
}
Exemplo n.º 24
0
void ssl_client_init()
{
    /*
     * This is twisted. We can generate the required keys by calling RSA_generate_key,
     * however we cannot put the private part and the public part in the two containers.
     * For that we need to save each part to a file and then load each part from
     * the respective file.
     */
    RSA *key = NULL;
    key = RSA_generate_key(1024, 17, NULL, NULL);
    if (!key)
    {
        correctly_initialized = false;
        return;
    }
    char name_template_private[] = "/tmp/tls_test/mnopqrXXXXXX";
    char name_template_public[] = "/tmp/tls_test/stuvwxXXXXXX";
    int private_key_file = 0;
    FILE *private_key_stream = NULL;
    int ret = 0;

    private_key_file = mkstemp(name_template_private);
    if (private_key_file < 0)
    {
        correctly_initialized = false;
        return;
    }
    private_key_stream = fdopen(private_key_file, "w+");
    if (!private_key_stream)
    {
        correctly_initialized = false;
        return;
    }
    ret = PEM_write_RSAPrivateKey(private_key_stream, key, NULL, NULL, 0, 0, NULL);
    if (ret == 0)
    {
        correctly_initialized = false;
        return;
    }
    fseek(private_key_stream, 0L, SEEK_SET);
    PRIVKEY = PEM_read_RSAPrivateKey(private_key_stream, (RSA **)NULL, NULL, NULL);
    if (!PRIVKEY)
    {
        correctly_initialized = false;
        return;
    }
    fclose(private_key_stream);

    int public_key_file = 0;
    FILE *public_key_stream = NULL;
    public_key_file = mkstemp(name_template_public);
    if (public_key_file < 0)
    {
        correctly_initialized = false;
        return;
    }
    public_key_stream = fdopen(public_key_file, "w+");
    if (!public_key_stream)
    {
        correctly_initialized = false;
        return;
    }
    ret = PEM_write_RSAPublicKey(public_key_stream, key);
    if (ret == 0)
    {
        correctly_initialized = false;
        return;
    }
    fseek(public_key_stream, 0L, SEEK_SET);
    PUBKEY = PEM_read_RSAPublicKey(public_key_stream, (RSA **)NULL, NULL, NULL);
    if (!PUBKEY)
    {
        correctly_initialized = false;
        return;
    }
    fclose(public_key_stream);
    RSA_free(key);

    SSLCLIENTCONTEXT = SSL_CTX_new(SSLv23_client_method());
    if (SSLCLIENTCONTEXT == NULL)
    {
        Log(LOG_LEVEL_ERR, "SSL_CTX_new: %s",
            ERR_reason_error_string(ERR_get_error()));
        goto err1;
    }

    /* Use only TLS v1 or later.
       TODO option for SSL_OP_NO_TLSv{1,1_1} */
    SSL_CTX_set_options(SSLCLIENTCONTEXT,
                        SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3);

    /* Never bother with retransmissions, SSL_write() should
     * always either write the whole amount or fail. */
    SSL_CTX_set_mode(SSLCLIENTCONTEXT, SSL_MODE_AUTO_RETRY);

    /*
     * Create cert into memory and load it into SSL context.
     */

    if (PRIVKEY == NULL || PUBKEY == NULL)
    {
        correctly_initialized = false;
        return;
    }

    /* Generate self-signed cert valid from now to 50 years later. */
    {
        X509 *x509 = X509_new();
        X509_gmtime_adj(X509_get_notBefore(x509), 0);
        X509_time_adj(X509_get_notAfter(x509), 60*60*24*365*50, NULL);
        EVP_PKEY *pkey = EVP_PKEY_new();
        EVP_PKEY_set1_RSA(pkey, PRIVKEY);
        X509_NAME *name = X509_get_subject_name(x509);
        X509_NAME_add_entry_by_txt(name, "CN", MBSTRING_ASC,
                                   (const char *) "",
                                   -1, -1, 0);
        X509_set_issuer_name(x509, name);
        X509_set_pubkey(x509, pkey);

        const EVP_MD *md = EVP_get_digestbyname("sha384");
        if (md == NULL)
        {
            correctly_initialized = false;
            return;
        }
        ret = X509_sign(x509, pkey, md);

        EVP_PKEY_free(pkey);
        SSLCLIENTCERT = x509;

        if (ret <= 0)
        {
            Log(LOG_LEVEL_ERR,
                "Couldn't sign the public key for the TLS handshake: %s",
                ERR_reason_error_string(ERR_get_error()));
            goto err3;
        }
    }
    /* Log(LOG_LEVEL_ERR, "generate cert from priv key: %s", */
    /*     ERR_reason_error_string(ERR_get_error())); */

    SSL_CTX_use_certificate(SSLCLIENTCONTEXT, SSLCLIENTCERT);

    ret = SSL_CTX_use_RSAPrivateKey(SSLCLIENTCONTEXT, PRIVKEY);
    if (ret != 1)
    {
        Log(LOG_LEVEL_ERR, "Failed to use RSA private key: %s",
            ERR_reason_error_string(ERR_get_error()));
        goto err3;
    }

    /* Verify cert consistency. */
    ret = SSL_CTX_check_private_key(SSLCLIENTCONTEXT);
    if (ret != 1)
    {
        Log(LOG_LEVEL_ERR, "Inconsistent key and TLS cert: %s",
            ERR_reason_error_string(ERR_get_error()));
        goto err3;
    }

    /* Set options to always request a certificate from the peer, either we
     * are client or server. */
    SSL_CTX_set_verify(SSLCLIENTCONTEXT, SSL_VERIFY_PEER, NULL);
    /* Always accept that certificate, we do proper checking after TLS
     * connection is established since OpenSSL can't pass a connection
     * specific pointer to the callback (so we would have to lock).  */
    SSL_CTX_set_cert_verify_callback(SSLCLIENTCONTEXT, TLSVerifyCallback, NULL);

    correctly_initialized = true;
    return;

  err3:
    X509_free(SSLCLIENTCERT);
    SSLCLIENTCERT = NULL;
    SSL_CTX_free(SSLCLIENTCONTEXT);
    SSLCLIENTCONTEXT = NULL;
  err1:
    correctly_initialized = false;
    return;
}
Exemplo n.º 25
0
/*
 * Write out a mount list
 */
void
rewrite_mtab(mntlist *mp, const char *mnttabname)
{
  FILE *mfp;
  int error = 0;

  /*
   * Concoct a temporary name in the same directory as the target mount
   * table so that rename() will work.
   */
  char tmpname[64];
  int retries;
  int tmpfd;
  char *cp;
  char mcp[128];

  xstrlcpy(mcp, mnttabname, sizeof(mcp));
  cp = strrchr(mcp, '/');
  if (cp) {
    memmove(tmpname, mcp, cp - mcp);
    tmpname[cp - mcp] = '\0';
  } else {
    plog(XLOG_WARNING, "No '/' in mtab (%s), using \".\" as tmp directory", mnttabname);
    tmpname[0] = '.';
    tmpname[1] = '\0';
  }
  xstrlcat(tmpname, "/mtabXXXXXX", sizeof(tmpname));
  retries = 0;
enfile1:
#ifdef HAVE_MKSTEMP
  tmpfd = mkstemp(tmpname);
  fchmod(tmpfd, 0644);
#else /* not HAVE_MKSTEMP */
  mktemp(tmpname);
  tmpfd = open(tmpname, O_RDWR | O_CREAT | O_TRUNC, 0644);
#endif /* not HAVE_MKSTEMP */
  if (tmpfd < 0) {
    if (errno == ENFILE && retries++ < NFILE_RETRIES) {
      sleep(1);
      goto enfile1;
    }
    plog(XLOG_ERROR, "%s: open: %m", tmpname);
    return;
  }
  if (close(tmpfd) < 0)
    plog(XLOG_ERROR, "Couldn't close tmp file descriptor: %m");

  retries = 0;
enfile2:
  mfp = setmntent(tmpname, "w");
  if (!mfp) {
    if (errno == ENFILE && retries++ < NFILE_RETRIES) {
      sleep(1);
      goto enfile2;
    }
    plog(XLOG_ERROR, "setmntent(\"%s\", \"w\"): %m", tmpname);
    error = 1;
    goto out;
  }
  while (mp) {
    if (mp->mnt) {
      if (addmntent(mfp, mp->mnt)) {
	plog(XLOG_ERROR, "Can't write entry to %s", tmpname);
	error = 1;
	goto out;
      }
    }
    mp = mp->mnext;
  }

  /*
   * SunOS 4.1 manuals say that the return code from entmntent()
   * is always 1 and to treat as a void.  That means we need to
   * call fflush() to make sure the new mtab file got written.
   */
  if (fflush(mfp)) {
    plog(XLOG_ERROR, "flush new mtab file: %m");
    error = 1;
    goto out;
  }
  (void) endmntent(mfp);

  /*
   * Rename temporary mtab to real mtab
   */
  if (rename(tmpname, mnttabname) < 0) {
    plog(XLOG_ERROR, "rename %s to %s: %m", tmpname, mnttabname);
    error = 1;
    goto out;
  }
out:
  if (error)
    (void) unlink(tmpname);
}
Exemplo n.º 26
0
static void
open_files(void)
{
    int fd;

    create_file_names();

    if (input_file == NULL)
    {
	input_file = fopen(input_file_name, "r");
	if (input_file == NULL)
	    open_error(input_file_name);
    }

    fd = mkstemp(action_file_name);
    if (fd < 0 || (action_file = fdopen(fd, "w")) == NULL) {
        if (fd >= 0)
	    close(fd);
	open_error(action_file_name);
    }
    fd = mkstemp(text_file_name);
    if (fd < 0 || (text_file = fdopen(fd, "w")) == NULL) {
        if (fd >= 0)
	    close(fd);
	open_error(text_file_name);
    }
    fd = mkstemp(union_file_name);
    if (fd < 0 || (union_file = fdopen(fd, "w")) == NULL) {
        if (fd >= 0)
	    close(fd);
	open_error(union_file_name);
    }

    text_file = fopen(text_file_name, "w");
    if (text_file == NULL)
	open_error(text_file_name);

    if (vflag)
    {
	verbose_file = fopen(verbose_file_name, "w");
	if (verbose_file == NULL)
	    open_error(verbose_file_name);
    }

    if (dflag)
    {
	defines_file = fopen(defines_file_name, "w");
	if (defines_file == NULL)
	    open_error(defines_file_name);
	union_file = fopen(union_file_name, "w");
	if (union_file ==  NULL)
	    open_error(union_file_name);
    }

    output_file = fopen(output_file_name, "w");
    if (output_file == NULL)
	open_error(output_file_name);

    if (rflag)
    {
	code_file = fopen(code_file_name, "w");
	if (code_file == NULL)
	    open_error(code_file_name);
    }
    else
	code_file = output_file;
}
Exemplo n.º 27
0
/**
 * Renames proxyfile according to format
 * When fmt contains %d it is replace with the target uid, when it ends with
 * XXXXXX it is replaced by a random string using mkstemp(). Upon success, the
 * new proxyfile will be put in the credential structure.
 * \param cred credential structure
 * \param fmt filename format string
 * \err errno in case of error
 * \return LCMAPSD_SUCCESS on success or lcmapsd_err_t error string
 */
lcmapsd_err_t _lcmapsd_rename(cred_t *cred, const char *fmt, int *err) {
    char *newfile=NULL,*buffer=NULL;
    int len,fd;
    struct stat buf;
    int prc;

    /* Check we need to do something */
    if (cred->proxyfile==NULL || fmt==NULL)
	return LCMAPSD_NO_ACTION;
    
    /* Open old file */
    if ((fd=open(cred->proxyfile,O_RDONLY))==-1 ||
	fstat(fd,&buf)==-1)    {
	*err=errno;
	return LCMAPSD_RENAME_ERR;
    }
    /* Reserve mem */
    if ((buffer=malloc(buf.st_size))==NULL) {
	*err=errno;
        return LCMAPSD_OUT_OF_MEM;
    }
    /* Read old file */
    if (read(fd,buffer,buf.st_size)!=buf.st_size || close(fd)==-1)  {
	*err=errno;
	free(buffer);
	return LCMAPSD_RENAME_ERR;
    }

    /* Create new file: check for %d first */
    if (strstr(fmt,"%d")!=NULL)  {
        len=snprintf(newfile,0,fmt,cred->uid);
        if ( (newfile=malloc(len+1))==NULL)  {
	    *err=errno;
            return LCMAPSD_OUT_OF_MEM;
	}
        snprintf(newfile,len+1,fmt,cred->uid);
    } else { /* No %d */
        len=strlen(fmt);
        if ( (newfile=strdup(fmt))==NULL)	{
	    *err=errno;
            return LCMAPSD_OUT_OF_MEM;
	}
    }

    /* Check for XXXXXX */
    if (strcmp(&(newfile[len-6]),"XXXXXX")==0)	{
	/* Check if the newname is of the same form as the old */
	if (strncmp(newfile,cred->proxyfile,len-6)==0)	{
	    free(newfile);
	    return LCMAPSD_NO_ACTION;
	}
	fd=mkstemp(newfile);
    } else    {
	/* Check if the newname is the same as the old */
	if (strcmp(newfile,cred->proxyfile)==0)	{
	    free(newfile);
	    return LCMAPSD_NO_ACTION;
	}
	fd=open(newfile,O_WRONLY | O_CREAT, S_IRUSR | S_IWUSR);
    }
    /* Check it has been opened successfully */
    if (fd==-1)	{
	*err=errno;
	free(newfile);
	return LCMAPSD_RENAME_ERR;
    }

    /* chown it to the original file and write buffer to it */
    if (fchown(fd,buf.st_uid,buf.st_gid)==-1 ||
	write(fd,buffer,buf.st_size)!=buf.st_size)  {
	/* Writing new file failed, remove it again, close() might fail, but we
	 * are cleaning up in any case */
	*err=errno;
	close(fd);
	unlink(newfile);
	free(newfile);
	return LCMAPSD_RENAME_ERR;
    }

    /* Close new file */
    if (close(fd)==-1) {
	*err=errno;
	unlink(newfile);
	free(newfile);
	return LCMAPSD_RENAME_ERR;
    }
   
    /* free memory */
    free(buffer);
    
    /* remove old file */
    if (unlink(cred->proxyfile)==-1)	{
	*err=errno;
	prc=LCMAPSD_RENAME_ERR;
    } else
	prc=LCMAPSD_SUCCESS;

    /* Update proxyfile to point to the new one */
    free(cred->proxyfile);
    cred->proxyfile=newfile;

    return prc;
}
Exemplo n.º 28
0
int
do_configure(config_object_t *config, const char *config_file)
{
	FILE *fp = NULL;
	char message[80];
	char tmp_filename[4096];
	int tmp_fd = -1;
	mode_t old_umask;

	if (sc_parse(config, config_file) != 0) {
		printf("Parsing of %s failed.\n", config_file);
		if (yesno("Start from scratch", 0) == 0) {
			return 1;
		}
	}

	plugin_path_configure(config);
	listener_configure(config);
	backend_configure(config);

	printf("\nConfiguration complete.\n\n");

	printf("=== Begin Configuration ===\n");
	sc_dump(config, stdout);
	printf("=== End Configuration ===\n");

	snprintf(message, sizeof(message), "Replace %s with the above",
		 config_file);
	if (yesno(message, 0) == 0) {
		return 1;
	}

	snprintf(tmp_filename, sizeof(tmp_filename),
		 "%s.XXXXXX", config_file);

	old_umask = umask(077);
	tmp_fd = mkstemp(tmp_filename);
	umask(old_umask);

	if (tmp_fd < 0) {
		perror("fopen");
		printf("Failed to write configuration file!\n");
		return 1;
	}

	fp = fdopen(tmp_fd, "w+");
	if (fp == NULL)
		goto out_fail;

	sc_dump(config, fp);

	if (rename(tmp_filename, config_file) < 0) {
		perror("rename");
		goto out_fail;
	}

	fclose(fp);
	close(tmp_fd);

	return 0;

out_fail:
	if (fp)
		fclose(fp);
	if (tmp_fd >= 0)
		close(tmp_fd);
	if (strlen(tmp_filename))
		unlink(tmp_filename);
	printf("Failed to write configuration file!\n");
	return 1;
}
Exemplo n.º 29
0
/* We have parsed a 'certif:' attribute from a 'key-cert' object.
 * Now perform the check to make sure the hexid specified in the
 * 'key-cert:' attribute matches the hexid from the 'certif:'
 * attribute.  We perform this check (and others) by adding the
 * 'certif:' attribute/PGP key block to a temp ring and parsing
 * the output from PGP.  Additionally, we check the following:
 *
 *  1. make sure there is only 1 hexid in the key
 *  2. make sure there is at least 1 owner/uid specified
 *  3. make sure we get a 'Successful' return string from PGP
 *  4. call get_fingerprint () to get the key fingerprint
 *     which checks to make sure there is only 1 fingerprint
 *
 * Return:
 *
 *    file name of key certificate file if there were no errors found
 *      - the file can then be used to easily add the PGP key to the
 *        local ring
 *      - the key fingerprint and owner(s)/uid(s) are saved to be
 *        used for the corresponding 'key-cert' auto-generated fields
 *    NULL otherwise
 */
char *hexid_check (parse_info_t *o) {
#ifdef PGP
  char pgpinfn[256], tmp_pgp_dir[256], ebuf[1024];
  FILE *pgpin;
  char_list_t *p;
  pgp_data_t pdat;
  int pgp_errors = 0, fd;
#endif

  /* If we don't have PGP installed then there is nothing to do. */
#ifndef PGP
    error_msg_queue (o, "PGP is not installed on the system.  Cannot perform operation.", ERROR_MSG);
    return NULL;
#else

  /* make a tmp directory for the pgp rings */
  umask (0022);
  strcpy (tmp_pgp_dir, "/var/tmp/pgp.XXXXXX");
  if (mkdtemp (tmp_pgp_dir) == NULL) {
    error_msg_queue (o, "Internal error.  Couldn't create temp directory for PGP\n", ERROR_MSG);
    return NULL;
  }

  /* create a file and put the key certificate into it */
  strcpy (pgpinfn, "/var/tmp/irrsyntax.XXXXXX");
  fd = mkstemp (pgpinfn);
  if ((pgpin = fdopen (fd, "w")) == NULL) {
    error_msg_queue (o, 
"Internal error.  Could not check 'key-cert:' temp file creation error", ERROR_MSG);
    goto pgp_errors_jump;
  }
  fwrite (o->u.kc.certif, sizeof (char), strlen (o->u.kc.certif), pgpin);
  fclose (pgpin);

  /* add the certificate to a temp ring */
  if (!pgp_add (default_trace, tmp_pgp_dir, pgpinfn, &pdat)) {
    error_msg_queue (o, "Couldn't add key-cert to ring.  Didn't get successful reply from PGP", ERROR_MSG);
    goto pgp_errors_jump;
  }

  /* certificate checks */

  /* do we have more than 1 hex ID? */
  if (pdat.hex_cnt > 1) {
    error_msg_queue (o, "Too many public keys in certificate", ERROR_MSG);
    pgp_errors = 1;
  }
  /* does the hex ID of the 'key-cert' attr match the certificate hex ID ? */
  else if (strcmp (pdat.hex_first->key, o->u.kc.kchexid)) {
    snprintf (ebuf, 1024, "Hex-ID mistmatch: 'key-cert:' (%s)  'certif:' (%s)\n",
	     o->u.kc.kchexid, pdat.hex_first->key);
    error_msg_queue (o, ebuf, ERROR_MSG);
    pgp_errors = 1;
  }
  /* owner check */
  else if (pdat.owner_first == NULL) {
    error_msg_queue (o, "No uid's/owners found in certificate", ERROR_MSG);
    pgp_errors = 1;
  }
  /* grab all the owners */
  else {
    o->u.kc.owner_count = pdat.owner_cnt;
    for (p = pdat.owner_first; p != NULL; p = p->next)
      o->u.kc.owner = my_concat (o->u.kc.owner, p->key, 0);
  }

  /* get the key fingerprint */
  if (!pgp_errors && 
      !get_fingerprint (o, tmp_pgp_dir, &pdat)) 
    pgp_errors = 1;

  if (o->u.kc.owner != NULL)
    if (verbose) fprintf (dfile, 
	     "owner count (%d) owner (%s)\n", o->u.kc.owner_count, o->u.kc.owner);
  if (o->u.kc.fingerpr != NULL)
    if (verbose) fprintf (dfile, "fingerpr (%s)\n", o->u.kc.fingerpr);

  /* end debug */

  /* clean up */
  pgp_free (&pdat);

  /* if we have errors then we won't need the key file */
  if (pgp_errors) {
pgp_errors_jump:
    rm_tmpdir (tmp_pgp_dir);  /* can get rid of temporary directory */
    remove (pgpinfn); 
    return NULL;
  }

  rm_tmpdir (tmp_pgp_dir);  /* can get rid of temporary directory */

  /* leave pgp key for possible addition to local ring */
  return strdup (pgpinfn);
#endif
}
Exemplo n.º 30
0
/*
 * expand_builtin - evaluate built-in macros.
 */
void
expand_builtin(const char *argv[], int argc, int td)
{
	int c, n;
	int ac;
	static int sysval = 0;

#ifdef DEBUG
	printf("argc = %d\n", argc);
	for (n = 0; n < argc; n++)
		printf("argv[%d] = %s\n", n, argv[n]);
	fflush(stdout);
#endif

 /*
  * if argc == 3 and argv[2] is null, then we
  * have macro-or-builtin() type call. We adjust
  * argc to avoid further checking..
  */
 /* we keep the initial value for those built-ins that differentiate
  * between builtin() and builtin.
  */
	ac = argc;

	if (argc == 3 && !*(argv[2]) && !mimic_gnu)
		argc--;

	switch (td & TYPEMASK) {

	case DEFITYPE:
		if (argc > 2)
			dodefine(argv[2], (argc > 3) ? argv[3] : null);
		break;

	case PUSDTYPE:
		if (argc > 2)
			dopushdef(argv[2], (argc > 3) ? argv[3] : null);
		break;

	case DUMPTYPE:
		dodump(argv, argc);
		break;

	case TRACEONTYPE:
		dotrace(argv, argc, 1);
		break;

	case TRACEOFFTYPE:
		dotrace(argv, argc, 0);
		break;

	case EXPRTYPE:
	/*
	 * doexpr - evaluate arithmetic
	 * expression
	 */
	{
		int base = 10;
		int maxdigits = 0;
		const char *errstr;

		if (argc > 3) {
			base = strtonum(argv[3], 2, 36, &errstr);
			if (errstr) {
				m4errx(1, "expr: base %s invalid.", argv[3]);
			}
		}
		if (argc > 4) {
			maxdigits = strtonum(argv[4], 0, INT_MAX, &errstr);
			if (errstr) {
				m4errx(1, "expr: maxdigits %s invalid.", argv[4]);
			}
		}
		if (argc > 2)
			pbnumbase(expr(argv[2]), base, maxdigits);
		break;
	}

	case IFELTYPE:
		if (argc > 4)
			doifelse(argv, argc);
		break;

	case IFDFTYPE:
	/*
	 * doifdef - select one of two
	 * alternatives based on the existence of
	 * another definition
	 */
		if (argc > 3) {
			if (lookup_macro_definition(argv[2]) != NULL)
				pbstr(argv[3]);
			else if (argc > 4)
				pbstr(argv[4]);
		}
		break;

	case LENGTYPE:
	/*
	 * dolen - find the length of the
	 * argument
	 */
		pbnum((argc > 2) ? strlen(argv[2]) : 0);
		break;

	case INCRTYPE:
	/*
	 * doincr - increment the value of the
	 * argument
	 */
		if (argc > 2)
			pbnum(atoi(argv[2]) + 1);
		break;

	case DECRTYPE:
	/*
	 * dodecr - decrement the value of the
	 * argument
	 */
		if (argc > 2)
			pbnum(atoi(argv[2]) - 1);
		break;

	case SYSCTYPE:
	/*
	 * dosys - execute system command
	 */
		if (argc > 2) {
			fflush(stdout);
			sysval = system(argv[2]);
		}
		break;

	case SYSVTYPE:
	/*
	 * dosysval - return value of the last
	 * system call.
	 *
	 */
		pbnum(sysval);
		break;

	case ESYSCMDTYPE:
		if (argc > 2)
			doesyscmd(argv[2]);
		break;
	case INCLTYPE:
		if (argc > 2)
			if (!doincl(argv[2])) {
				if (mimic_gnu) {
					warn("%s at line %lu: include(%s)",
					    CURRENT_NAME, CURRENT_LINE, argv[2]);
					exit_code = 1;
				} else
					err(1, "%s at line %lu: include(%s)",
					    CURRENT_NAME, CURRENT_LINE, argv[2]);
			}
		break;

	case SINCTYPE:
		if (argc > 2)
			(void) doincl(argv[2]);
		break;
#ifdef EXTENDED
	case PASTTYPE:
		if (argc > 2)
			if (!dopaste(argv[2]))
				err(1, "%s at line %lu: paste(%s)", 
				    CURRENT_NAME, CURRENT_LINE, argv[2]);
		break;

	case SPASTYPE:
		if (argc > 2)
			(void) dopaste(argv[2]);
		break;
	case FORMATTYPE:
		doformat(argv, argc);
		break;
#endif
	case CHNQTYPE:
		dochq(argv, ac);
		break;

	case CHNCTYPE:
		dochc(argv, argc);
		break;

	case SUBSTYPE:
	/*
	 * dosub - select substring
	 *
	 */
		if (argc > 3)
			dosub(argv, argc);
		break;

	case SHIFTYPE:
	/*
	 * doshift - push back all arguments
	 * except the first one (i.e. skip
	 * argv[2])
	 */
		if (argc > 3) {
			for (n = argc - 1; n > 3; n--) {
				pbstr(rquote);
				pbstr(argv[n]);
				pbstr(lquote);
				pushback(COMMA);
			}
			pbstr(rquote);
			pbstr(argv[3]);
			pbstr(lquote);
		}
		break;

	case DIVRTYPE:
		if (argc > 2 && (n = atoi(argv[2])) != 0)
			dodiv(n);
		else {
			active = stdout;
			oindex = 0;
		}
		break;

	case UNDVTYPE:
		doundiv(argv, argc);
		break;

	case DIVNTYPE:
	/*
	 * dodivnum - return the number of
	 * current output diversion
	 */
		pbnum(oindex);
		break;

	case UNDFTYPE:
	/*
	 * doundefine - undefine a previously
	 * defined macro(s) or m4 keyword(s).
	 */
		if (argc > 2)
			for (n = 2; n < argc; n++)
				macro_undefine(argv[n]);
		break;

	case POPDTYPE:
	/*
	 * dopopdef - remove the topmost
	 * definitions of macro(s) or m4
	 * keyword(s).
	 */
		if (argc > 2)
			for (n = 2; n < argc; n++)
				macro_popdef(argv[n]);
		break;

	case MKTMTYPE:
	/*
	 * dotemp - create a temporary file
	 */
		if (argc > 2) {
			int fd;
			char *temp;

			temp = xstrdup(argv[2]);

			fd = mkstemp(temp);
			if (fd == -1)
				err(1,
	    "%s at line %lu: couldn't make temp file %s",
	    CURRENT_NAME, CURRENT_LINE, argv[2]);
			close(fd);
			pbstr(temp);
			free(temp);
		}
		break;

	case TRNLTYPE:
	/*
	 * dotranslit - replace all characters in
	 * the source string that appears in the
	 * "from" string with the corresponding
	 * characters in the "to" string.
	 */
		if (argc > 3) {
			char *temp;

			temp = xalloc(strlen(argv[2])+1, NULL);
			if (argc > 4)
				map(temp, argv[2], argv[3], argv[4]);
			else
				map(temp, argv[2], argv[3], null);
			pbstr(temp);
			free(temp);
		} else if (argc > 2)
			pbstr(argv[2]);
		break;

	case INDXTYPE:
	/*
	 * doindex - find the index of the second
	 * argument string in the first argument
	 * string. -1 if not present.
	 */
		pbnum((argc > 3) ? indx(argv[2], argv[3]) : -1);
		break;

	case ERRPTYPE:
	/*
	 * doerrp - print the arguments to stderr
	 * file
	 */
		if (argc > 2) {
			for (n = 2; n < argc; n++)
				fprintf(stderr, "%s ", argv[n]);
			fprintf(stderr, "\n");
		}
		break;

	case DNLNTYPE:
	/*
	 * dodnl - eat-up-to and including
	 * newline
	 */
		while ((c = gpbc()) != '\n' && c != EOF)
			;
		break;

	case M4WRTYPE:
	/*
	 * dom4wrap - set up for
	 * wrap-up/wind-down activity
	 */
		if (argc > 2)
			dom4wrap(argv[2]);
		break;

	case EXITTYPE:
	/*
	 * doexit - immediate exit from m4.
	 */
		killdiv();
		exit((argc > 2) ? atoi(argv[2]) : 0);
		break;

	case DEFNTYPE:
		if (argc > 2)
			for (n = 2; n < argc; n++)
				dodefn(argv[n]);
		break;

	case INDIRTYPE:	/* Indirect call */
		if (argc > 2)
			doindir(argv, argc);
		break;

	case BUILTINTYPE: /* Builtins only */
		if (argc > 2)
			dobuiltin(argv, argc);
		break;

	case PATSTYPE:
		if (argc > 2)
			dopatsubst(argv, argc);
		break;
	case REGEXPTYPE:
		if (argc > 2)
			doregexp(argv, argc);
		break;
	case LINETYPE:
		doprintlineno(infile+ilevel);
		break;
	case FILENAMETYPE:
		doprintfilename(infile+ilevel);
		break;
	case SELFTYPE:
		pbstr(rquote);
		pbstr(argv[1]);
		pbstr(lquote);
		break;
	default:
		m4errx(1, "eval: major botch.");
		break;
	}
}