help-gnats
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: gnats queue sorting question


From: Chad Walstrom
Subject: Re: gnats queue sorting question
Date: Fri, 04 Dec 2009 01:37:52 -0600

Hey, Alex.

I know it's been a long time since you last wrote about this, but I've
cracked open my vim editor and started to poke around again into this
stuff.

I've looked at the maildir specification at
http://cr.yp.to/proto/maildir.html, and believe it to be relatively easy
to implement this as a naming structure.  I've chosen to go with:

   seconds.MmicrosecondsPpidQdeliveries.hostname

Here's a test example code snippet to generate the unique name. I didn't
research HOST_NAME_MAX and ENAMETOOLONG much past looking at the man
pages for glibc and POSIX.  We could probably put this in an autoconf
check.

I began to look at readdir and found that the readdir_r version has some
badness to it.

http://womble.decadentplace.org.uk/readdir_r-advisory.html (2005)

Using scandir sounds like a great idea, and possibly we could find a
version of it lying around for those libraries that don't yet have it,
i.e. POSIX.

The "(int)" casting I did in the printf statement is probably wrong, but
this is a quick hack.  (Probably use %lu instead, or something.)  Again,
if we use something like this, we could autoconf check for pid_t (should
be there no matter what), time_t and suseconds_t and what do do about
them.

Hostname sizes (potentially 255), and file name sizes (potentially a max
of 255), could obviously collide, so an snprintf() call could be used to
limit to the maximum file length.

I wonder if it's all that necessary to use a temporary directory or not,
but it looks like we're currently using one in queue-pr.c, so keeping
that symantec is probably fine.  We could essentially rip out the
asprintf build of the template string and use a normal open() call
rather than the open_temporary_file().

Oh... and by the way...  It feels good to hack in C again. :)

/* gcc -o uniquename uniquename.c */
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>

#ifndef HOST_NAME_MAX
#define HOST_NAME_MAX 255
#endif


/* Get a hostname clean enough for Maildir unique names */
int get_cleaned_hostname(char *hostname, int len)
{
  /* Retrieve the host name */
  if (0 != gethostname(hostname, len))
    {
      /* Only works if GNU Glibc is being used */
      if (errno == EINVAL
#ifdef ENAMETOOLONG
          || errno == ENAMETOOLONG)
#endif
        {
          perror("Name was too long\n");
        }
      else if (errno == EFAULT)
        {
          perror("Invalid hostname.\n");
          return(-1);
        }
      else
        {
          perror("Unknown error condition.\n");
          return(-1);
        }
    }

  /* Clean up the hostname -- cannot have '/' or ':' */
  int i = 0;
  for (i;i < len;i++)
    {
      if ('/' == hostname[i])
        {
          fprintf(stderr, "Found a '/' at index %d.\n", i);
          hostname[i] = '\057';
        }
      else if (':' == hostname[i])
        {
          fprintf(stderr, "Found a ':' at index %d.\n", i);
          hostname[i] = '\072';
        }
      else if (' ' == hostname[i])
        {
          fprintf(stderr, "Found a ' ' at index %d.\n", i);
          hostname[i] = '\040';
        }
      else if ('\0' == hostname[i])
        {
          break;
        }
    }

  return(0);
}

/* Let's see what it takes to make a unique file name. */
int main (int argc, char **argv)
{
  struct timeval tv;
  char hostname[HOST_NAME_MAX];
  int deliveries = 0;

  if (0 != get_cleaned_hostname(hostname, HOST_NAME_MAX))
    {
      perror("Couldn't retrieve hostname.\n");
      exit(-1);
    }

  /**
  for(deliveries;deliveries < HOST_NAME_MAX; deliveries++) {
   * Get the time of day -- potentially lots of system calls
   * if for..loop starts before here. Guaranteed more unique
   * names.  If we're counting deliveries, which we should,
   * the for..loop should follow this call.
   **/
  if (0 != gettimeofday(&tv, NULL))
    {
      perror("Could not get time of day.\n");
      exit(-1);
    }
  for (deliveries;deliveries < HOST_NAME_MAX; deliveries++)
    {
      printf("%d.M%dP%dQ%d.%s\n", (int) tv.tv_sec, (int) tv.tv_usec, (int) 
getpid(), deliveries, hostname);
    }
}




reply via email to

[Prev in Thread] Current Thread [Next in Thread]