Example #1
0
/* al_findnext:
 *  Retrieves the next file from a directory search.
 */
int al_findnext(struct al_ffblk *info)
{
   char tempname[FF_MAXPATHLEN];
   char filename[FF_MAXPATHLEN];
   int attrib;
   struct dirent *entry;
   struct stat s;
   struct FF_DATA *ff_data = (struct FF_DATA *) info->ff_data;

   ASSERT(ff_data);

   /* if the pattern contained no wildcard */
   if (!ff_data->dir)
      return -1;

   while (TRUE) {
      /* read directory entry */
      entry = readdir(ff_data->dir);
      if (!entry) {
         *allegro_errno = (errno ? errno : ENOENT);
         return -1;
      }

      /* try to match file name with pattern */
      tempname[0] = 0;
      if (NAMLEN(entry) >= sizeof(tempname))
         strncat(tempname, entry->d_name, sizeof(tempname) - 1);
      else
         strncat(tempname, entry->d_name, NAMLEN(entry));

      if (ff_match(tempname, ff_data->pattern)) {
         _al_sane_strncpy(filename, ff_data->dirname, FF_MAXPATHLEN);
         ff_put_backslash(filename, sizeof(filename));
         strncat(filename, tempname, sizeof(filename) - strlen(filename) - 1);

         /* get file attributes */
         if (stat(filename, &s) == 0) {
            attrib = ff_get_attrib(tempname, &s);

            /* does it match ? */
            if ((attrib & ~ff_data->attrib) == 0)
               break;
         }
         else {
            /* evil! but no other way to avoid exiting for_each_file() */
            *allegro_errno = 0;
         }
      }
   }

   info->attrib = attrib;
   info->time = s.st_mtime;
   info->size = s.st_size; /* overflows at 2GB */
   ff_data->size = s.st_size;

   do_uconvert(tempname, U_UTF8, info->name, U_CURRENT, sizeof(info->name));

   return 0;
}
int
next_saved_game(struct ffblk *ffblk)
{
	struct dirent *dp;
	int len;

	memset(ffblk, 0, sizeof *ffblk);

	if (save_dir == NULL)
		return (1);

	while ((dp = readdir(save_dir)) != NULL)
	{
		len = NAMLEN(dp);
		if (len < 4)
			continue;
		if (xstrncasecmp(dp->d_name + len - 4, ".SAV", 4) != 0)
			continue;

		strncpy(ffblk->ff_name, dp->d_name, sizeof ffblk->ff_name);
		ffblk->ff_name[sizeof ffblk->ff_name - 1] = 0;

		return (0);
	}

	return (1);
}
void
catdir(const char *dir, int recursive, int colorize, int lighten, int rotate)
{
    char *end;
    DIR *dirf;
    struct dirent *ent;
    namelink_t *recursion = 0;
    namelink_t *free_namelink = 0;

  again:
    end = strchr(dir, '\0');

    if (end - 2 >= dir && end[-1] == '/' && end[-2] == '/')
        recursive = 1;
    while (end - 2 > dir && end[-1] == '/' && end[-2] == '/')
        end--;

    if (!(dirf = opendir(dir))) {
        perror(dir);
        goto next;
    }

    while ((ent = readdir(dirf))) {
        const char *s = ent->d_name;
        int ent_namlen = NAMLEN(ent);
        namelink_t *n = (namelink_t *) makedirnam(dir, end, ent, offsetof(namelink_t, name));
        struct stat sbuf;

        // don't depend on unreliable parts of the dirent structure
        if (stat(n->name, &sbuf) < 0)
            /* do nothing */;
        else if (S_ISREG(sbuf.st_mode) && ent_namlen > 4
                 && s[ent_namlen - 4] == '.'
                 && tolower((unsigned char) s[ent_namlen - 3]) == 'g'
                 && tolower((unsigned char) s[ent_namlen - 2]) == 'i'
                 && tolower((unsigned char) s[ent_namlen - 1]) == 'f') {
            addcat(n->name, colorize, lighten, rotate);
            n = 0;              /* do not free */
        } else if (S_ISDIR(sbuf.st_mode) && recursive
                   && (ent_namlen > 1 || s[0] != '.')
                   && (ent_namlen > 2 || s[0] != '.' || s[1] != '.')) {
            n->next = recursion;
            recursion = n;
            n = 0;              /* do not free */
        }

        free(n);
    }

    closedir(dirf);

  next:
    free(free_namelink);
    if (recursion) {
        free_namelink = recursion;
        recursion = recursion->next;
        dir = free_namelink->name;
        goto again;
    }
}
Example #4
0
StrVec listdir (const char *name)
{
    StrVec file_list;
#ifdef _MSC_VER
    HANDLE hFindFile;
    WIN32_FIND_DATA FileData;
    char namebuf [MAX_PATH*2+5];

    strncpy (namebuf, name, sizeof (namebuf));

    int len = strlen (namebuf);
    if (len > 0)
    {
        char ch = namebuf [len-1];
        if (ch != PATH_SEPARATOR && ch != ':')
            namebuf [len++] = PATH_SEPARATOR;
    }
    strncpy (namebuf + len, "*", sizeof (namebuf) - len);
    hFindFile = FindFirstFile (namebuf, &FileData);
    if (hFindFile == INVALID_HANDLE_VALUE) return file_list;
    do {
        if (FileData.cFileName[0] == '.' &&
            (FileData.cFileName[1] == '\0' ||
            FileData.cFileName[1] == '.' &&
            FileData.cFileName[2] == '\0'))
            continue;
        file_list.push_back (FileData.cFileName);
    } while (FindNextFile (hFindFile, &FileData) == TRUE);
    FindClose (hFindFile);
#else
    DIR *dirp;
    struct dirent *ep;
    if ((dirp = opendir (name)) == NULL) {
        return file_list;
    }
    while ((ep = readdir (dirp)) != NULL) {
        if (ep->d_name[0] == '.' &&
            (NAMLEN (ep) == 1 ||
            (ep->d_name[1] == '.' && NAMLEN(ep) == 2)))
            continue;
        file_list.push_back (std::string(ep->d_name, NAMLEN (ep)));
    }
    closedir(dirp);
#endif
    return file_list;
}
Example #5
0
File: fileio.c Project: barak/lush
at *files(const char *s)
{
   at *ans = NIL;
   at **where = &ans;

#ifdef UNIX
   DIR *dirp = opendir(s);
   if (dirp) {
      struct dirent *d;
      while ((d = readdir(dirp))) {
         int n = NAMLEN(d);
         at *ats = make_string_of_length(n);
         char *s = (char *)String(ats);
         strncpy(s, d->d_name, n); s[n] = 0;
         *where = new_cons(ats,NIL);
         where = &Cdr(*where);
      }
      closedir(dirp);
   }
#endif

#ifdef WIN32

   struct _finddata_t info;

   if ((s[0]=='/' || s[0]=='\\') && 
       (s[1]=='/' || s[1]=='\\') && !s[2]) {
      long hfind = GetLogicalDrives();
      strcpy(info.name,"A:\\");
      for (info.name[0]='A'; info.name[0]<='Z'; info.name[0]++)
         if (hfind & (1<<(info.name[0]-'A'))) {
            *where = new_cons(new_string(info.name),NIL);
            where = &Cdr(*where);
         }
   } else if (dirp(s)) {
      *where = new_cons(new_string(".."),NIL);
      where = &Cdr(*where);
   }
   strcpy(string_buffer,s);
   char *last = string_buffer + strlen(string_buffer);
   if (last>string_buffer && last[-1]!='/' && last[-1]!='\\')
      strcpy(last,"\\*.*");
   else 
      strcpy(last,"*.*");
   long hfind = _findfirst(string_buffer, &info);
   if (hfind != -1) {
      do {
         if (strcmp(".",info.name) && strcmp("..",info.name)) {
            *where = new_cons(new_string(info.name),NIL);
            where = &Cdr(*where);
         }
      } while ( _findnext(hfind, &info) != -1 );
      _findclose(hfind);
   }
#endif
   return ans;
}
static char *
makedirnam(const char *dir, const char *end, const struct dirent *ent, int extra)
{
    int ent_namlen = NAMLEN(ent);
    char *x = (char *) malloc(end - dir + 2 + ent_namlen + extra) + extra;
    char *y = x + (end - dir);
    memcpy(x, dir, end - dir);
    if (end[-1] != '/')
        *y++ = '/';
    memcpy(y, ent->d_name, ent_namlen);
    y[ent_namlen] = '\0';
    return x - extra;
}
Example #7
0
/*
 *  call-seq:
 *     dir.each { |filename| block }  => dir
 *
 *  Calls the block once for each entry in this directory, passing the
 *  filename of each entry as a parameter to the block.
 *
 *     d = Dir.new("testdir")
 *     d.each  {|x| puts "Got #{x}" }
 *
 *  <em>produces:</em>
 *
 *     Got .
 *     Got ..
 *     Got config.h
 *     Got main.rb
 */
static VALUE
dir_each(VALUE dir)
{
    struct dir_data *dirp;
    struct dirent *dp;

    RETURN_ENUMERATOR(dir, 0, 0);
    GetDIR(dir, dirp);
    rewinddir(dirp->dir);
    for (dp = readdir(dirp->dir); dp != NULL; dp = readdir(dirp->dir)) {
	rb_yield(dir_enc_str(rb_tainted_str_new(dp->d_name, NAMLEN(dp)), dirp));
	if (dirp->dir == NULL) dir_closed();
    }
    return dir;
}
Example #8
0
/*
 *  call-seq:
 *     dir.read => string or nil
 *
 *  Reads the next entry from <em>dir</em> and returns it as a string.
 *  Returns <code>nil</code> at the end of the stream.
 *
 *     d = Dir.new("testdir")
 *     d.read   #=> "."
 *     d.read   #=> ".."
 *     d.read   #=> "config.h"
 */
static VALUE
dir_read(VALUE dir)
{
    struct dir_data *dirp;
    struct dirent *dp;

    GetDIR(dir, dirp);
    errno = 0;
    dp = readdir(dirp->dir);
    if (dp) {
	return dir_enc_str(rb_tainted_str_new(dp->d_name, NAMLEN(dp)), dirp);
    }
    else if (errno == 0) {	/* end of stream */
	return Qnil;
    }
    else {
	rb_sys_fail(0);
    }
    return Qnil;		/* not reached */
}
Example #9
0
static int highest_version (
     char * filename,
     char * dirname)
{
    DIR           * dirp = opendir (dirname);
    struct dirent * dp = NULL;
    int             highestVersion;

    if (!dirp)
    {
        highestVersion = 0;
    }
    else
    {
       int             this_version;
       unsigned int    file_name_length = strlen(filename);

       highestVersion = 0;

       while ((dp = readdir (dirp)) != 0)
       {
          if (!REAL_DIR_ENTRY (dp) || NAMLEN (dp) <= file_name_length + 2)
          {
             continue;
          }


          this_version = version_number (filename, dp->d_name, file_name_length);

          if (this_version > highestVersion)
          {
             highestVersion = this_version;
          }
       }

       closedir (dirp);
    }

    return highestVersion;
}
Example #10
0
/* HandleInputLine is NOT thread safe - due to readdir issues,
   resolving them portably is not really simple. */
int HandleInputLine(
    int argc,
    char **argv,
    FILE * out)
{
#if defined(HAVE_OPENDIR) && defined (HAVE_READDIR)
    DIR      *curdir;   /* to read current dir with ls */
    struct dirent *dent;
#endif
#if defined(HAVE_SYS_STAT_H)
    struct stat st;
#endif

    /* Reset errno to 0 before we start.
     */
    if (RemoteMode) {
        if (argc > 1 && strcmp("quit", argv[1]) == 0) {
            if (argc > 2) {
                printf("ERROR: invalid parameter count for quit\n");
                return (1);
            }
            exit(0);
        }
#if defined(HAVE_OPENDIR) && defined(HAVE_READDIR) && defined(HAVE_CHDIR)
        if (argc > 1 && strcmp("cd", argv[1]) == 0) {
            if (argc > 3) {
                printf("ERROR: invalid parameter count for cd\n");
                return (1);
            }
#if ! defined(HAVE_CHROOT) || ! defined(HAVE_GETUID)
            if (getuid() == 0 && !ChangeRoot) {
                printf
                ("ERROR: chdir security problem - rrdtool is running as "
                 "root but not chroot!\n");
                return (1);
            }
#endif
            if (chdir(argv[2]) != 0) {
                printf("ERROR: chdir %s %s\n", argv[2], rrd_strerror(errno));
                return (1);
            }
            return (0);
        }
        if (argc > 1 && strcmp("pwd", argv[1]) == 0) {
            char     *cwd;      /* To hold current working dir on call to pwd */
            if (argc > 2) {
                printf("ERROR: invalid parameter count for pwd\n");
                return (1);
            }
            cwd = getcwd(NULL, MAXPATH);
            if (cwd == NULL) {
                printf("ERROR: getcwd %s\n", rrd_strerror(errno));
                return (1);
            }
            printf("%s\n", cwd);
            free(cwd);
            return (0);
        }
        if (argc > 1 && strcmp("mkdir", argv[1]) == 0) {
            if (argc > 3) {
                printf("ERROR: invalid parameter count for mkdir\n");
                return (1);
            }
#if ! defined(HAVE_CHROOT) || ! defined(HAVE_GETUID)
            if (getuid() == 0 && !ChangeRoot) {
                printf
                ("ERROR: mkdir security problem - rrdtool is running as "
                 "root but not chroot!\n");
                return (1);
            }
#endif
            if(mkdir(argv[2], 0777)!=0) {
                printf("ERROR: mkdir %s: %s\n", argv[2],rrd_strerror(errno));
                return (1);
            }
            return (0);
        }
        if (argc > 1 && strcmp("ls", argv[1]) == 0) {
            if (argc > 2) {
                printf("ERROR: invalid parameter count for ls\n");
                return (1);
            }
            if ((curdir = opendir(".")) != NULL) {
                while ((dent = readdir(curdir)) != NULL) {
                    if (!stat(dent->d_name, &st)) {
                        if (S_ISDIR(st.st_mode)) {
                            printf("d %s\n", dent->d_name);
                        }
                        if (strlen(dent->d_name) > 4 && S_ISREG(st.st_mode)) {
                            if (!strcmp
                                    (dent->d_name + NAMLEN(dent) - 4, ".rrd")
                                    || !strcmp(dent->d_name + NAMLEN(dent) - 4,
                                               ".RRD")) {
                                printf("- %s\n", dent->d_name);
                            }
                        }
                    }
                }
                closedir(curdir);
            } else {
                printf("ERROR: opendir .: %s\n", rrd_strerror(errno));
                return (errno);
            }
            return (0);
        }
#endif                          /* opendir and readdir */

    }
    if (argc < 3
            || strcmp("help", argv[1]) == 0
            || strcmp("--help", argv[1]) == 0
            || strcmp("-help", argv[1]) == 0
            || strcmp("-?", argv[1]) == 0 || strcmp("-h", argv[1]) == 0) {
        PrintUsage("");
        return 0;
    }

    if (strcmp("create", argv[1]) == 0)
        rrd_create(argc - 1, &argv[1]);
    else if (strcmp("dump", argv[1]) == 0)
        rrd_dump(argc - 1, &argv[1]);
    else if (strcmp("info", argv[1]) == 0 || strcmp("updatev", argv[1]) == 0) {
        rrd_info_t *data;

        if (strcmp("info", argv[1]) == 0)

            data = rrd_info(argc - 1, &argv[1]);
        else
            data = rrd_update_v(argc - 1, &argv[1]);
        rrd_info_print(data);
        rrd_info_free(data);
    }

    else if (strcmp("--version", argv[1]) == 0 ||
             strcmp("version", argv[1]) == 0 ||
             strcmp("v", argv[1]) == 0 ||
             strcmp("-v", argv[1]) == 0 || strcmp("-version", argv[1]) == 0)
        printf("RRDtool " PACKAGE_VERSION
               "  Copyright by Tobi Oetiker, 1997-2008 (%f)\n",
               rrd_version());
    else if (strcmp("restore", argv[1]) == 0)
        rrd_restore(argc - 1, &argv[1]);
    else if (strcmp("resize", argv[1]) == 0)
        rrd_resize(argc - 1, &argv[1]);
    else if (strcmp("last", argv[1]) == 0)
        printf("%ld\n", rrd_last(argc - 1, &argv[1]));
    else if (strcmp("lastupdate", argv[1]) == 0) {
        rrd_lastupdate(argc - 1, &argv[1]);
    } else if (strcmp("first", argv[1]) == 0)
        printf("%ld\n", rrd_first(argc - 1, &argv[1]));
    else if (strcmp("update", argv[1]) == 0)
        rrd_update(argc - 1, &argv[1]);
    else if (strcmp("fetch", argv[1]) == 0) {
        time_t    start, end, ti;
        unsigned long step, ds_cnt, i, ii;
        rrd_value_t *data, *datai;
        char    **ds_namv;

        if (rrd_fetch
                (argc - 1, &argv[1], &start, &end, &step, &ds_cnt, &ds_namv,
                 &data) != -1) {
            datai = data;
            printf("           ");
            for (i = 0; i < ds_cnt; i++)
                printf("%20s", ds_namv[i]);
            printf("\n\n");
            for (ti = start + step; ti <= end; ti += step) {
                printf("%10lu:", ti);
                for (ii = 0; ii < ds_cnt; ii++)
                    printf(" %0.10e", *(datai++));
                printf("\n");
            }
            for (i = 0; i < ds_cnt; i++)
                free(ds_namv[i]);
            free(ds_namv);
            free(data);
        }
    } else if (strcmp("xport", argv[1]) == 0) {
        int       xxsize;
        unsigned long int j = 0;
        time_t    start, end, ti;
        unsigned long step, col_cnt, row_cnt;
        rrd_value_t *data, *ptr;
        char    **legend_v;
        int       enumds = 0;
        int       i;
        size_t    vtag_s = strlen(COL_DATA_TAG) + 10;
        char     *vtag = malloc(vtag_s);

        for (i = 2; i < argc; i++) {
            if (strcmp("--enumds", argv[i]) == 0)
                enumds = 1;
        }

        if (rrd_xport
                (argc - 1, &argv[1], &xxsize, &start, &end, &step, &col_cnt,
                 &legend_v, &data) != -1) {
            char *old_locale = setlocale(LC_NUMERIC, "C");
            row_cnt = (end - start) / step;
            ptr = data;
            printf("<?xml version=\"1.0\" encoding=\"%s\"?>\n\n",
                   XML_ENCODING);
            printf("<%s>\n", ROOT_TAG);
            printf("  <%s>\n", META_TAG);
            printf("    <%s>%lld</%s>\n", META_START_TAG,
                   (long long int) start + step, META_START_TAG);
            printf("    <%s>%lu</%s>\n", META_STEP_TAG, step, META_STEP_TAG);
            printf("    <%s>%lld</%s>\n", META_END_TAG, (long long int) end,
                   META_END_TAG);
            printf("    <%s>%lu</%s>\n", META_ROWS_TAG, row_cnt,
                   META_ROWS_TAG);
            printf("    <%s>%lu</%s>\n", META_COLS_TAG, col_cnt,
                   META_COLS_TAG);
            printf("    <%s>\n", LEGEND_TAG);
            for (j = 0; j < col_cnt; j++) {
                char     *entry = NULL;

                entry = legend_v[j];
                printf("      <%s>%s</%s>\n", LEGEND_ENTRY_TAG, entry,
                       LEGEND_ENTRY_TAG);
                free(entry);
            }
            free(legend_v);
            printf("    </%s>\n", LEGEND_TAG);
            printf("  </%s>\n", META_TAG);
            printf("  <%s>\n", DATA_TAG);
            for (ti = start + step; ti <= end; ti += step) {
                printf("    <%s>", DATA_ROW_TAG);
                printf("<%s>%lld</%s>", COL_TIME_TAG, (long long int)ti, COL_TIME_TAG);
                for (j = 0; j < col_cnt; j++) {
                    rrd_value_t newval = DNAN;

                    if (enumds == 1)

                        snprintf(vtag, vtag_s, "%s%lu", COL_DATA_TAG, j);
                    else
                        snprintf(vtag, vtag_s, "%s", COL_DATA_TAG);
                    newval = *ptr;
                    if (isnan(newval)) {
                        printf("<%s>NaN</%s>", vtag, vtag);
                    } else {
                        printf("<%s>%0.10e</%s>", vtag, newval, vtag);
                    };
                    ptr++;
                }
                printf("</%s>\n", DATA_ROW_TAG);
            }
            free(data);
            printf("  </%s>\n", DATA_TAG);
            printf("</%s>\n", ROOT_TAG);
            setlocale(LC_NUMERIC, old_locale);
        }
        free(vtag);
    } else if (strcmp("graph", argv[1]) == 0) {
        char    **calcpr;

#ifdef notused /*XXX*/
        const char *imgfile = argv[2];  /* rrd_graph changes argv pointer */
#endif
        int       xsize, ysize;
        double    ymin, ymax;
        int       i;
        int       tostdout = (strcmp(argv[2], "-") == 0);
        int       imginfo = 0;

        for (i = 2; i < argc; i++) {
            if (strcmp(argv[i], "--imginfo") == 0
                    || strcmp(argv[i], "-f") == 0) {
                imginfo = 1;
                break;
            }
        }
        if (rrd_graph
                (argc - 1, &argv[1], &calcpr, &xsize, &ysize, NULL, &ymin,
                 &ymax) != -1) {
            if (!tostdout && !imginfo)
                printf("%dx%d\n", xsize, ysize);
            if (calcpr) {
                for (i = 0; calcpr[i]; i++) {
                    if (!tostdout)
                        printf("%s\n", calcpr[i]);
                    free(calcpr[i]);
                }
                free(calcpr);
            }
        }

    } else if (strcmp("graphv", argv[1]) == 0) {
        rrd_info_t *grinfo = NULL;  /* 1 to distinguish it from the NULL that rrd_graph sends in */

        grinfo = rrd_graph_v(argc - 1, &argv[1]);
        if (grinfo) {
            rrd_info_print(grinfo);
            rrd_info_free(grinfo);
        }

    } else if (strcmp("tune", argv[1]) == 0)
        rrd_tune(argc - 1, &argv[1]);
    else if (strcmp("flushcached", argv[1]) == 0)
        rrd_flushcached(argc - 1, &argv[1]);
    else {
        rrd_set_error("unknown function '%s'", argv[1]);
    }
    if (rrd_test_error()) {
        fprintf(out, "ERROR: %s\n", rrd_get_error());
        rrd_clear_error();
        return 1;
    }
    return (0);
}
Example #11
0
char *
savedir (const char *dir, off_t name_size)
{
  DIR *dirp;
  struct dirent *dp;
  char *name_space;
  char *namep;

  dirp = opendir (dir);
  if (dirp == NULL)
    return NULL;

  /* Be sure name_size is at least `1' so there's room for
     the final NUL byte.  */
  if (name_size <= 0)
    name_size = 1;

  name_space = (char *) malloc (name_size);
  if (name_space == NULL)
    {
      closedir (dirp);
      return NULL;
    }
  namep = name_space;

  while ((dp = readdir (dirp)) != NULL)
    {
      /* Skip "." and ".." (some NFS filesystems' directories lack them). */
      if (dp->d_name[0] != '.'
	  || (dp->d_name[1] != '\0'
	      && (dp->d_name[1] != '.' || dp->d_name[2] != '\0')))
	{
	  off_t size_needed = (namep - name_space) + NAMLEN (dp) + 2;

	  if (size_needed > name_size)
	    {
	      char *new_name_space;

	      while (size_needed > name_size)
		name_size += 1024;

	      new_name_space = realloc (name_space, name_size);
	      if (new_name_space == NULL)
		{
		  closedir (dirp);
		  return NULL;
		}
	      namep += new_name_space - name_space;
	      name_space = new_name_space;
	    }
	  namep = stpcpy (namep, dp->d_name) + 1;
	}
    }
  *namep = '\0';
  if (CLOSEDIR (dirp))
    {
      free (name_space);
      return NULL;
    }
  return name_space;
}
Example #12
0
ftw_dir (struct ftw_data *data, struct STAT *st, struct dir_data *old_dir)
{
  struct dir_data dir;
  struct dirent64 *d;
  int previous_base = data->ftw.base;
  int result;
  char *startp;

  /* Open the stream for this directory.  This might require that
     another stream has to be closed.  */
  result = open_dir_stream (old_dir == NULL ? NULL : &old_dir->streamfd,
			    data, &dir);
  if (result != 0)
    {
      if (errno == EACCES)
	/* We cannot read the directory.  Signal this with a special flag.  */
	result = (*data->func) (data->dirbuf, st, FTW_DNR, &data->ftw);

      return result;
    }

  /* First, report the directory (if not depth-first).  */
  if (!(data->flags & FTW_DEPTH))
    {
      result = (*data->func) (data->dirbuf, st, FTW_D, &data->ftw);
      if (result != 0)
	{
	  int save_err;
fail:
	  save_err = errno;
	  __closedir (dir.stream);
	  dir.streamfd = -1;
	  __set_errno (save_err);

	  if (data->actdir-- == 0)
	    data->actdir = data->maxdir - 1;
	  data->dirstreams[data->actdir] = NULL;
	  return result;
	}
    }

  /* If necessary, change to this directory.  */
  if (data->flags & FTW_CHDIR)
    {
      if (__fchdir (__dirfd (dir.stream)) < 0)
	{
	  result = -1;
	  goto fail;
	}
    }

  /* Next, update the `struct FTW' information.  */
  ++data->ftw.level;
  startp = __rawmemchr (data->dirbuf, '\0');
  /* There always must be a directory name.  */
  assert (startp != data->dirbuf);
  if (startp[-1] != '/')
    *startp++ = '/';
  data->ftw.base = startp - data->dirbuf;

  while (dir.stream != NULL && (d = __readdir64 (dir.stream)) != NULL)
    {
      int d_type = DT_UNKNOWN;
#ifdef _DIRENT_HAVE_D_TYPE
      d_type = d->d_type;
#endif
      result = process_entry (data, &dir, d->d_name, NAMLEN (d), d_type);
      if (result != 0)
	break;
    }

  if (dir.stream != NULL)
    {
      /* The stream is still open.  I.e., we did not need more
	 descriptors.  Simply close the stream now.  */
      int save_err = errno;

      assert (dir.content == NULL);

      __closedir (dir.stream);
      dir.streamfd = -1;
      __set_errno (save_err);

      if (data->actdir-- == 0)
	data->actdir = data->maxdir - 1;
      data->dirstreams[data->actdir] = NULL;
    }
  else
    {
      int save_err;
      char *runp = dir.content;

      while (result == 0 && *runp != '\0')
	{
	  char *endp = strchr (runp, '\0');

	  // XXX Should store the d_type values as well?!
	  result = process_entry (data, &dir, runp, endp - runp, DT_UNKNOWN);

	  runp = endp + 1;
	}

      save_err = errno;
      free (dir.content);
      __set_errno (save_err);
    }

  if ((data->flags & FTW_ACTIONRETVAL) && result == FTW_SKIP_SIBLINGS)
    result = 0;

  /* Prepare the return, revert the `struct FTW' information.  */
  data->dirbuf[data->ftw.base - 1] = '\0';
  --data->ftw.level;
  data->ftw.base = previous_base;

  /* Finally, if we process depth-first report the directory.  */
  if (result == 0 && (data->flags & FTW_DEPTH))
    result = (*data->func) (data->dirbuf, st, FTW_DP, &data->ftw);

  if (old_dir
      && (data->flags & FTW_CHDIR)
      && (result == 0
	  || ((data->flags & FTW_ACTIONRETVAL)
	      && (result != -1 && result != FTW_STOP))))
    {
      /* Change back to the parent directory.  */
      int done = 0;
      if (old_dir->stream != NULL)
	if (__fchdir (__dirfd (old_dir->stream)) == 0)
	  done = 1;

      if (!done)
	{
	  if (data->ftw.base == 1)
	    {
	      if (__chdir ("/") < 0)
		result = -1;
	    }
	  else
	    if (__chdir ("..") < 0)
	      result = -1;
	}
    }

  return result;
}
Example #13
0
open_dir_stream (int *dfdp, struct ftw_data *data, struct dir_data *dirp)
{
  int result = 0;

  if (data->dirstreams[data->actdir] != NULL)
    {
      /* Oh, oh.  We must close this stream.  Get all remaining
	 entries and store them as a list in the `content' member of
	 the `struct dir_data' variable.  */
      size_t bufsize = 1024;
      char *buf = malloc (bufsize);

      if (buf == NULL)
	result = -1;
      else
	{
	  DIR *st = data->dirstreams[data->actdir]->stream;
	  struct dirent64 *d;
	  size_t actsize = 0;

	  while ((d = __readdir64 (st)) != NULL)
	    {
	      size_t this_len = NAMLEN (d);
	      if (actsize + this_len + 2 >= bufsize)
		{
		  char *newp;
		  bufsize += MAX (1024, 2 * this_len);
		  newp = (char *) realloc (buf, bufsize);
		  if (newp == NULL)
		    {
		      /* No more memory.  */
		      int save_err = errno;
		      free (buf);
		      __set_errno (save_err);
		      return -1;
		    }
		  buf = newp;
		}

	      *((char *) __mempcpy (buf + actsize, d->d_name, this_len))
		= '\0';
	      actsize += this_len + 1;
	    }

	  /* Terminate the list with an additional NUL byte.  */
	  buf[actsize++] = '\0';

	  /* Shrink the buffer to what we actually need.  */
	  data->dirstreams[data->actdir]->content = realloc (buf, actsize);
	  if (data->dirstreams[data->actdir]->content == NULL)
	    {
	      int save_err = errno;
	      free (buf);
	      __set_errno (save_err);
	      result = -1;
	    }
	  else
	    {
	      __closedir (st);
	      data->dirstreams[data->actdir]->stream = NULL;
	      data->dirstreams[data->actdir]->streamfd = -1;
	      data->dirstreams[data->actdir] = NULL;
	    }
	}
    }

  /* Open the new stream.  */
  if (result == 0)
    {
      assert (data->dirstreams[data->actdir] == NULL);

      if (dfdp != NULL && *dfdp != -1)
	{
	  int fd = __openat64_nocancel (*dfdp, data->dirbuf + data->ftw.base,
					O_RDONLY | O_DIRECTORY | O_NDELAY);
	  dirp->stream = NULL;
	  if (fd != -1 && (dirp->stream = __fdopendir (fd)) == NULL)
	    __close_nocancel_nostatus (fd);
	}
      else
	{
	  const char *name;

	  if (data->flags & FTW_CHDIR)
	    {
	      name = data->dirbuf + data->ftw.base;
	      if (name[0] == '\0')
		name = ".";
	    }
	  else
	    name = data->dirbuf;

	  dirp->stream = __opendir (name);
	}

      if (dirp->stream == NULL)
	result = -1;
      else
	{
	  dirp->streamfd = __dirfd (dirp->stream);
	  dirp->content = NULL;
	  data->dirstreams[data->actdir] = dirp;

	  if (++data->actdir == data->maxdir)
	    data->actdir = 0;
	}
    }

  return result;
}
Example #14
0
void
incremental_restore (int skipcrud)
{
  char *current_dir;
  char *archive_dir;
  struct accumulator *accumulator;
  char *p;
  DIR *dirp;
  struct dirent *d;
  char *cur, *arc;
  long size;
  size_t size_to_copy;
  union block *data_block;
  char *to;

#define CURRENT_FILE_NAME (skipcrud + current.name)

  dirp = opendir (CURRENT_FILE_NAME);

  if (!dirp)
    {
      /* The directory doesn't exist now.  It'll be created.  In any
	 case, we don't have to delete any files out of it.  */

      skip_file (current.stat.st_size);
      return;
    }

  accumulator = new_accumulator ();
  while (d = readdir (dirp), d)
    {
      if (is_dot_or_dotdot (d->d_name))
	continue;

      add_to_accumulator (accumulator, d->d_name, NAMLEN (d) + 1);
    }
  closedir (dirp);
  add_to_accumulator (accumulator, "", (size_t) 1);

  current_dir = get_accumulator (accumulator);
  archive_dir = (char *) xmalloc ((size_t) current.stat.st_size);
  to = archive_dir;
  for (size = current.stat.st_size; size > 0; size -= size_to_copy)
    {
      data_block = find_next_block ();
      if (!data_block)
	{
	  ERROR ((0, 0, _("Unexpected end of file in archive")));
	  break;		/* FIXME: What happens then?  */
	}
      size_to_copy = available_space_after (data_block);
      if (size_to_copy > size)
	size_to_copy = size;
      memcpy (to, data_block->buffer, size_to_copy);
      to += size_to_copy;
      set_next_block_after ((union block *)
			    (data_block->buffer + size_to_copy - 1));
    }

  for (cur = current_dir; *cur; cur += strlen (cur) + 1)
    {
      for (arc = archive_dir; *arc; arc += strlen (arc) + 1)
	{
	  arc++;
	  if (!strcmp (arc, cur))
	    break;
	}
      if (*arc == '\0')
	{
	  p = concat_with_slash (CURRENT_FILE_NAME, cur);
	  if (interactive_option && !confirm (_("delete %s?"), p))
	    {
	      free (p);
	      continue;
	    }
	  if (verbose_option)
	    {
	      if (checkpoint_option)
		flush_progress_dots ();
	      fprintf (stdlis, _("%s: Deleting %s\n"), program_name, p);
	    }
	  if (!remove_any_file (p, true))
	    ERROR ((0, errno, _("Error while deleting %s"), p));
	  free (p);
	}

    }
  delete_accumulator (accumulator);
  free (archive_dir);

#undef CURRENT_FILE_NAME
}
Example #15
0
char *
get_directory_contents (char *path, dev_t device)
{
  struct accumulator *accumulator;

  /* Recursively scan the given PATH.  */

  {
    DIR *dirp = opendir (path);	/* for scanning directory */
    struct dirent *entry;	/* directory entry being scanned */
    char *name_buffer;		/* directory, `/', and directory member */
    size_t name_buffer_size;	/* allocated size of name_buffer, minus 2 */
    size_t name_length;		/* used length in name_buffer */
    struct directory *directory; /* for checking if already already seen */
    bool all_children;

    if (dirp == NULL)
      {
	ERROR ((0, errno, _("Cannot open directory %s"), path));
	return NULL;
      }
    errno = 0;			/* FIXME: errno should be read-only */

    name_buffer_size = strlen (path) + NAME_FIELD_SIZE;
    name_buffer = xmalloc (name_buffer_size + 2);
    strcpy (name_buffer, path);
    if (path[strlen (path) - 1] != '/')
      strcat (name_buffer, "/");
    name_length = strlen (name_buffer);

    directory = find_directory (path);
    all_children = directory ? directory->all_new : false;

    accumulator = new_accumulator ();

    while (entry = readdir (dirp), entry)
      {
	struct stat stat_info;

	/* Skip `.' and `..'.  */

	if (is_dot_or_dotdot (entry->d_name))
	  continue;

	if (NAMLEN (entry) + name_length >= name_buffer_size)
	  {
	    while (NAMLEN (entry) + name_length >= name_buffer_size)
	      name_buffer_size += NAME_FIELD_SIZE;
	    name_buffer = (char *)
	      xrealloc (name_buffer, name_buffer_size + 2);
	  }
	strcpy (name_buffer + name_length, entry->d_name);

	if (dereference_option
#ifdef AIX
	    ? statx (name_buffer, &stat_info, STATSIZE, STX_HIDDEN)
	    : statx (name_buffer, &stat_info, STATSIZE, STX_HIDDEN | STX_LINK)
#else
	    ? stat (name_buffer, &stat_info)
	    : lstat (name_buffer, &stat_info)
#endif
	    )
	  {
	    ERROR ((0, errno, _("Cannot stat %s"), name_buffer));
	    continue;
	  }

	if ((one_file_system_option && device != stat_info.st_dev)
	    || (exclude_option && check_exclude (name_buffer)))
	  add_to_accumulator (accumulator, "N", (size_t) 1);

#ifdef AIX
	else if (S_ISHIDDEN (stat_info.st_mode))
	  {
	    add_to_accumulator (accumulator, "D", (size_t) 1);
	    strcat (entry->d_name, "A");
	    entry->d_namlen++;
	  }
#endif

	else if (S_ISDIR (stat_info.st_mode))
	  {
	    if (directory = find_directory (name_buffer), directory)
	      {
		/* The same file can have two different devices if an NFS
		   directory is mounted in multiple locations, which is
		   relatively common when automounting.  For avoiding
		   spurious incremental redumping of directories, we have to
		   plainly consider all NFS devices as equal, relying on the
		   i-node only to establish differences.

		   Devices having the high bit set usually are NFS devices.  */

		/* FIXME: Göran Uddeborg <*****@*****.**> says, on
		   1996-09-20, that SunOS 5/Solaris 2 uses unsigned long for
		   the device number type.  */

		if ((((short) directory->device_number >= 0
		      || (short) stat_info.st_dev >= 0)
		     && directory->device_number != stat_info.st_dev)
		    || directory->inode_number != stat_info.st_ino)
		  {
		    if (verbose_option)
		      WARN ((0, 0, _("Directory %s has been renamed"),
			     name_buffer));
		    directory->all_new = true;
		    directory->device_number = stat_info.st_dev;
		    directory->inode_number = stat_info.st_ino;
		  }
		directory->dir_text = "";
	      }
	    else
	      {
		if (verbose_option)
		  WARN ((0, 0, _("Directory %s is new"), name_buffer));
		note_directory (name_buffer,
				stat_info.st_dev, stat_info.st_ino, "");
		directory = find_directory (name_buffer);
		directory->all_new = true;
	      }
	    if (all_children && directory)
	      directory->all_new = true;

	    add_to_accumulator (accumulator, "D", (size_t) 1);
	  }

	else
	  if (all_children || FILE_IS_NEW_ENOUGH (&stat_info))
	    add_to_accumulator (accumulator, "Y", (size_t) 1);
	  else
	    add_to_accumulator (accumulator, "N", (size_t) 1);

	add_to_accumulator (accumulator, entry->d_name, NAMLEN (entry) + 1);
      }
    add_to_accumulator (accumulator, "\000\000", (size_t) 2);

    free (name_buffer);
    closedir (dirp);
  }

  /* Sort the contents of the directory, now that we have it all.  */

  {
    char *pointer = get_accumulator (accumulator);
    size_t counter;
    char *cursor;
    char *buffer;
    char **array;
    char **array_cursor;

    counter = 0;
    for (cursor = pointer; *cursor; cursor += strlen (cursor) + 1)
      counter++;

    if (counter == 0)
      {
	delete_accumulator (accumulator);
	return NULL;
      }

    array = (char **) xmalloc (sizeof (char *) * (counter + 1));

    array_cursor = array;
    for (cursor = pointer; *cursor; cursor += strlen (cursor) + 1)
      *array_cursor++ = cursor;
    *array_cursor = NULL;

    qsort ((voidstar) array, counter, sizeof (char *), compare_dirents);

    buffer = (char *) xmalloc ((size_t) (cursor - pointer + 2));

    cursor = buffer;
    for (array_cursor = array; *array_cursor; array_cursor++)
      {
	char *string = *array_cursor;

	while ((*cursor++ = *string++))
	  continue;
      }
    *cursor = '\0';

    delete_accumulator (accumulator);
    free (array);
    return buffer;
  }
}
Example #16
0
static int
list_session_dir(char *pathbuf, REGEX_T *re, const char *user, const char *tty)
{
    FILE *fp;
    DIR *d;
    struct dirent *dp;
    char *buf = NULL, *cmd = NULL, *cwd = NULL, idstr[7], *cp;
    struct log_info li;
    size_t bufsize = 0, cwdsize = 0, cmdsize = 0, plen;

    plen = strlen(pathbuf);
    d = opendir(pathbuf);
    if (d == NULL && errno != ENOTDIR) {
	warning("cannot opendir %s", pathbuf);
	return -1;
    }
    while ((dp = readdir(d)) != NULL) {
	if (NAMLEN(dp) != 2 || !isalnum((unsigned char)dp->d_name[0]) ||
	    !isalnum((unsigned char)dp->d_name[1]))
	    continue;

	/* open log file, print id and command */
	pathbuf[plen + 0] = '/';
	pathbuf[plen + 1] = dp->d_name[0];
	pathbuf[plen + 2] = dp->d_name[1];
	pathbuf[plen + 3] = '/';
	pathbuf[plen + 4] = 'l';
	pathbuf[plen + 5] = 'o';
	pathbuf[plen + 6] = 'g';
	pathbuf[plen + 7] = '\0';
	fp = fopen(pathbuf, "r");
	if (fp == NULL) {
	    warning("unable to open %s", pathbuf);
	    continue;
	}

	/*
	 * ID file has three lines:
	 *  1) a log info line
	 *  2) cwd
	 *  3) command with args
	 */
	if (getline(&buf, &bufsize, fp) == -1 ||
	    getline(&cwd, &cwdsize, fp) == -1 ||
	    getline(&cmd, &cmdsize, fp) == -1) {
	    fclose(fp);
	    continue;
	}
	fclose(fp);

	/* crack the log line: timestamp:user:runas_user:runas_group:tty */
	buf[strcspn(buf, "\n")] = '\0';
	if ((li.tstamp = atoi(buf)) == 0)
	    continue;

	if ((cp = strchr(buf, ':')) == NULL)
	    continue;
	*cp++ = '\0';
	li.user = cp;

	if ((cp = strchr(cp, ':')) == NULL)
	    continue;
	*cp++ = '\0';
	li.runas_user = cp;

	if ((cp = strchr(cp, ':')) == NULL)
	    continue;
	*cp++ = '\0';
	li.runas_group = cp;

	if ((cp = strchr(cp, ':')) == NULL)
	    continue;
	*cp++ = '\0';
	li.tty = cp;

	cwd[strcspn(cwd, "\n")] = '\0';
	li.cwd = cwd;

	cmd[strcspn(cmd, "\n")] = '\0';
	li.cmd = cmd;

	/* Match on search expression if there is one. */
	if (search_expr && !match_expr(search_expr, &li))
	    continue;

	/* Convert from /var/log/sudo-sessions/00/00/01 to 000001 */
	idstr[0] = pathbuf[plen - 5];
	idstr[1] = pathbuf[plen - 4];
	idstr[2] = pathbuf[plen - 2];
	idstr[3] = pathbuf[plen - 1];
	idstr[4] = pathbuf[plen + 1];
	idstr[5] = pathbuf[plen + 2];
	idstr[6] = '\0';
	printf("%s : %s : TTY=%s ; CWD=%s ; USER=%s ; ",
	    get_timestr(li.tstamp, 1), li.user, li.tty, li.cwd, li.runas_user);
	if (*li.runas_group)
	    printf("GROUP=%s ; ", li.runas_group);
	printf("TSID=%s ; COMMAND=%s\n", idstr, li.cmd);
    }
    return 0;
}
Example #17
0
static int
list_sessions(int argc, char **argv, const char *pattern, const char *user,
    const char *tty)
{
    DIR *d1, *d2;
    struct dirent *dp1, *dp2;
    REGEX_T rebuf, *re = NULL;
    size_t sdlen;
    char pathbuf[PATH_MAX];

    /* Parse search expression if present */
    parse_expr(&search_expr, argv);

    d1 = opendir(session_dir);
    if (d1 == NULL)
	error(1, "unable to open %s", session_dir);

#ifdef HAVE_REGCOMP
    /* optional regex */
    if (pattern) {
	re = &rebuf;
	if (regcomp(re, pattern, REG_EXTENDED|REG_NOSUB) != 0)
	    errorx(1, "invalid regex: %s", pattern);
    }
#else
    re = (char *) pattern;
#endif /* HAVE_REGCOMP */

    sdlen = strlcpy(pathbuf, session_dir, sizeof(pathbuf));
    if (sdlen + sizeof("/00/00/00/log") >= sizeof(pathbuf)) {
	errno = ENAMETOOLONG;
	error(1, "%s/00/00/00/log", session_dir);
    }

    /*
     * Three levels of directory, e.g. 00/00/00 .. ZZ/ZZ/ZZ
     * We do a depth-first traversal.
     */
    while ((dp1 = readdir(d1)) != NULL) {
	if (NAMLEN(dp1) != 2 || !isalnum((unsigned char)dp1->d_name[0]) ||
	    !isalnum((unsigned char)dp1->d_name[1]))
	    continue;

	pathbuf[sdlen + 0] = '/';
	pathbuf[sdlen + 1] = dp1->d_name[0];
	pathbuf[sdlen + 2] = dp1->d_name[1];
	pathbuf[sdlen + 3] = '\0';
	d2 = opendir(pathbuf);
	if (d2 == NULL)
	    continue;

	while ((dp2 = readdir(d2)) != NULL) {
	    if (NAMLEN(dp2) != 2 || !isalnum((unsigned char)dp2->d_name[0]) ||
		!isalnum((unsigned char)dp2->d_name[1]))
		continue;

	    pathbuf[sdlen + 3] = '/';
	    pathbuf[sdlen + 4] = dp2->d_name[0];
	    pathbuf[sdlen + 5] = dp2->d_name[1];
	    pathbuf[sdlen + 6] = '\0';
	    list_session_dir(pathbuf, re, user, tty);
	}
	closedir(d2);
    }
    closedir(d1);
    return 0;
}
Example #18
0
static int
lua_dir(lua_State *L)
{
  int k = 0;
  const char *s = luaL_checkstring(L, 1);

#ifdef _WIN32

  SB sb;
  struct _finddata_t info;
  long hfind;
  /* special cases */
  lua_createtable(L, 0, 0);
  if ((s[0]=='/' || s[0]=='\\') && 
      (s[1]=='/' || s[1]=='\\') && !s[2]) 
    {
      int drive;
      hfind = GetLogicalDrives();
      for (drive='A'; drive<='Z'; drive++)
        if (hfind & (1<<(drive-'A'))) {
          lua_pushfstring(L, "%c:/", drive);
          lua_rawseti(L, -2, ++k);
        }
    } 
  else if (dirp(L, 1)) {
    lua_pushliteral(L, "..");
    lua_rawseti(L, -2, ++k);
  } else {
    lua_pushnil(L);
    return 1;
  }
  /* files */
  sbinit(&sb);
  sbaddn(&sb, s, strlen(s));
  if (sb.len>0 && sb.buffer[sb.len-1]!='/' && sb.buffer[sb.len-1]!='\\')
    sbadd1(&sb, '/');
  sbaddn(&sb, "*.*", 3);
  sbadd1(&sb, 0);
  hfind = _findfirst(sb.buffer, &info);
  if (hfind != -1) {
    do {
      if (strcmp(".",info.name) && strcmp("..",info.name)) {
        lua_pushstring(L, info.name);
        lua_rawseti(L, -2, ++k);
      }
    } while ( _findnext(hfind, &info) != -1 );
    _findclose(hfind);
  }
  sbfree(&sb);

#else

  DIR *dirp;
  struct dirent *d;
  dirp = opendir(s);
  if (dirp) {
    lua_createtable(L, 0, 0);
    while ((d = readdir(dirp))) {
      int n = NAMLEN(d);
      lua_pushlstring(L, d->d_name, n);
      lua_rawseti(L, -2, ++k);
    }
    closedir(dirp);
  } else
    lua_pushnil(L);

#endif
  
  return 1;
}
Example #19
0
PyObject *listdir(PyObject *self, PyObject *args)
{
    char *name = NULL;
    PyObject *d, *v;
    DIR *dirp;
    struct dirent *ep;
    int arg_is_unicode = 1;

    errno = 0;
    if (!PyArg_ParseTuple(args, "U:listdir", &v)) {
        arg_is_unicode = 0;
        PyErr_Clear();
    }
    if (!PyArg_ParseTuple(args, "et:listdir", Py_FileSystemDefaultEncoding, &name))
        return NULL;
    if ((dirp = opendir(name)) == NULL) {
        return posix_error_with_allocated_filename(name);
    }
    if ((d = PyList_New(0)) == NULL) {
        closedir(dirp);
        PyMem_Free(name);
        return NULL;
    }
    for (;;) {
        errno = 0;
        Py_BEGIN_ALLOW_THREADS
        ep = readdir(dirp);
        Py_END_ALLOW_THREADS
        if (ep == NULL) {
            if (errno == 0) {
                break;
            } else {
                closedir(dirp);
                Py_DECREF(d);
                return posix_error_with_allocated_filename(name);
            }
        }
        if (ep->d_name[0] == '.' &&
            (NAMLEN(ep) == 1 ||
             (ep->d_name[1] == '.' && NAMLEN(ep) == 2)))
            continue;
        v = PyString_FromStringAndSize(ep->d_name, NAMLEN(ep));
        if (v == NULL) {
            Py_DECREF(d);
            d = NULL;
            break;
        }
#ifdef Py_USING_UNICODE
        if (arg_is_unicode) {
            PyObject *w;

            w = PyUnicode_FromEncodedObject(v,
                    Py_FileSystemDefaultEncoding,
                    "strict");
            if (w != NULL) {
                Py_DECREF(v);
                v = w;
            }
            else {
                /* fall back to the original byte string, as
                   discussed in patch #683592 */
                PyErr_Clear();
            }
        }
#endif
        if (PyList_Append(d, v) != 0) {
            Py_DECREF(v);
            Py_DECREF(d);
            d = NULL;
            break;
        }
        Py_DECREF(v);
    }
    closedir(dirp);
    PyMem_Free(name);

    return d;
}
Example #20
0
  /* This scandir is a shrink version of the glibc version.
   * I believe we don't need versionsort or any other sort in the ragnarok.
   */
SCM scm_mmr_scandir(SCM dir, SCM filter)
#define FUNC_NAME "scandir"
{
    struct dirent_or_dirent64 **rdent;
    int has_filter = 0;
    int n = 0 ,i = 0;
    char *tmp_ptr = NULL;
    SCM flag;
    SCM ret = SCM_EOL;
    SCM *prev;
    SCM str;

    SCM_VALIDATE_STRING(1, dir);

    if(!SCM_UNBNDP(filter))
	{
	    SCM_ASSERT(scm_is_true(scm_procedure_p(filter)),
		       filter ,SCM_ARG2 ,FUNC_NAME);
	    has_filter = 1;
	}

    scm_dynwind_begin(0);
    errno = 0;

    tmp_ptr = scm_to_locale_string(dir);
    scm_dynwind_free(tmp_ptr);

    n = scandir_or_scandir64(tmp_ptr,
			     &rdent, NULL,
			     alphasort_or_alphasort64);

    if(has_filter)
	{
	    for(prev = &ret;i<n;i++)
		{
		    str = rdent[i]?
			scm_from_locale_stringn(rdent[i]->d_name ,NAMLEN(rdent[i]))
			:
			SCM_EOF_VAL;
		    flag = scm_call_1(filter ,str);
		    free(rdent[i]);

		    if(scm_is_true(flag))
			{
			    *prev = scm_cons(str ,SCM_EOL);
			    prev = SCM_CDRLOC(*prev);
			}
		}
	}
    else
	{
	    for(prev = &ret;i<n;i++)
		{
		    str = rdent[i]?
			scm_from_locale_stringn(rdent[i]->d_name ,NAMLEN(rdent[i]))
			:
			SCM_EOF_VAL;
		    *prev = scm_cons(str ,SCM_EOL);
		    prev = SCM_CDRLOC(*prev);
		    free(rdent[i]);
		}
	}

    if(errno != 0)
	SCM_SYSERROR;

    scm_dynwind_end();

    free(rdent);
    
    return ret;
}
Example #21
0
Lisp_Object
directory_files_internal (Lisp_Object directory, Lisp_Object full, Lisp_Object match, Lisp_Object nosort, int attrs, Lisp_Object id_format)
{
  DIR *d;
  int directory_nbytes;
  Lisp_Object list, dirfilename, encoded_directory;
  struct re_pattern_buffer *bufp = NULL;
  int needsep = 0;
  int count = SPECPDL_INDEX ();
  struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5;
  DIRENTRY *dp;
#ifdef WINDOWSNT
  Lisp_Object w32_save = Qnil;
#endif

  /* Because of file name handlers, these functions might call
     Ffuncall, and cause a GC.  */
  list = encoded_directory = dirfilename = Qnil;
  GCPRO5 (match, directory, list, dirfilename, encoded_directory);
  dirfilename = Fdirectory_file_name (directory);

  if (!NILP (match))
    {
      CHECK_STRING (match);

      /* MATCH might be a flawed regular expression.  Rather than
	 catching and signaling our own errors, we just call
	 compile_pattern to do the work for us.  */
      /* Pass 1 for the MULTIBYTE arg
	 because we do make multibyte strings if the contents warrant.  */
# ifdef WINDOWSNT
      /* Windows users want case-insensitive wildcards.  */
      bufp = compile_pattern (match, 0,
			      BVAR (&buffer_defaults, case_canon_table), 0, 1);
# else	/* !WINDOWSNT */
      bufp = compile_pattern (match, 0, Qnil, 0, 1);
# endif	 /* !WINDOWSNT */
    }

  /* Note: ENCODE_FILE and DECODE_FILE can GC because they can run
     run_pre_post_conversion_on_str which calls Lisp directly and
     indirectly.  */
  if (STRING_MULTIBYTE (dirfilename))
    dirfilename = ENCODE_FILE (dirfilename);
  encoded_directory = (STRING_MULTIBYTE (directory)
		       ? ENCODE_FILE (directory) : directory);

  /* Now *bufp is the compiled form of MATCH; don't call anything
     which might compile a new regexp until we're done with the loop!  */

  BLOCK_INPUT;
  d = opendir (SSDATA (dirfilename));
  UNBLOCK_INPUT;
  if (d == NULL)
    report_file_error ("Opening directory", Fcons (directory, Qnil));

  /* Unfortunately, we can now invoke expand-file-name and
     file-attributes on filenames, both of which can throw, so we must
     do a proper unwind-protect.  */
  record_unwind_protect (directory_files_internal_unwind,
			 make_save_value (d, 0));

#ifdef WINDOWSNT
  if (attrs)
    {
      extern int is_slow_fs (const char *);

      /* Do this only once to avoid doing it (in w32.c:stat) for each
	 file in the directory, when we call Ffile_attributes below.  */
      record_unwind_protect (directory_files_internal_w32_unwind,
			     Vw32_get_true_file_attributes);
      w32_save = Vw32_get_true_file_attributes;
      if (EQ (Vw32_get_true_file_attributes, Qlocal))
	{
	  /* w32.c:stat will notice these bindings and avoid calling
	     GetDriveType for each file.  */
	  if (is_slow_fs (SDATA (dirfilename)))
	    Vw32_get_true_file_attributes = Qnil;
	  else
	    Vw32_get_true_file_attributes = Qt;
	}
    }
#endif

  directory_nbytes = SBYTES (directory);
  re_match_object = Qt;

  /* Decide whether we need to add a directory separator.  */
  if (directory_nbytes == 0
      || !IS_ANY_SEP (SREF (directory, directory_nbytes - 1)))
    needsep = 1;

  /* Loop reading blocks until EOF or error.  */
  for (;;)
    {
      errno = 0;
      dp = readdir (d);

      if (dp == NULL && (0
#ifdef EAGAIN
			 || errno == EAGAIN
#endif
#ifdef EINTR
			 || errno == EINTR
#endif
			 ))
	{ QUIT; continue; }

      if (dp == NULL)
	break;

      if (DIRENTRY_NONEMPTY (dp))
	{
	  int len;
	  int wanted = 0;
	  Lisp_Object name, finalname;
	  struct gcpro gcpro1, gcpro2;

	  len = NAMLEN (dp);
	  name = finalname = make_unibyte_string (dp->d_name, len);
	  GCPRO2 (finalname, name);

	  /* Note: DECODE_FILE can GC; it should protect its argument,
	     though.  */
	  name = DECODE_FILE (name);
	  len = SBYTES (name);

	  /* Now that we have unwind_protect in place, we might as well
             allow matching to be interrupted.  */
	  immediate_quit = 1;
	  QUIT;

	  if (NILP (match)
	      || (0 <= re_search (bufp, SSDATA (name), len, 0, len, 0)))
	    wanted = 1;

	  immediate_quit = 0;

	  if (wanted)
	    {
	      if (!NILP (full))
		{
		  Lisp_Object fullname;
		  int nbytes = len + directory_nbytes + needsep;
		  int nchars;

		  fullname = make_uninit_multibyte_string (nbytes, nbytes);
		  memcpy (SDATA (fullname), SDATA (directory),
			  directory_nbytes);

		  if (needsep)
		    SSET (fullname, directory_nbytes, DIRECTORY_SEP);

		  memcpy (SDATA (fullname) + directory_nbytes + needsep,
			  SDATA (name), len);

		  nchars = chars_in_text (SDATA (fullname), nbytes);

		  /* Some bug somewhere.  */
		  if (nchars > nbytes)
		    abort ();

		  STRING_SET_CHARS (fullname, nchars);
		  if (nchars == nbytes)
		    STRING_SET_UNIBYTE (fullname);

		  finalname = fullname;
		}
	      else
		finalname = name;

	      if (attrs)
		{
		  /* Construct an expanded filename for the directory entry.
		     Use the decoded names for input to Ffile_attributes.  */
		  Lisp_Object decoded_fullname, fileattrs;
		  struct gcpro gcpro1, gcpro2;

		  decoded_fullname = fileattrs = Qnil;
		  GCPRO2 (decoded_fullname, fileattrs);

		  /* Both Fexpand_file_name and Ffile_attributes can GC.  */
		  decoded_fullname = Fexpand_file_name (name, directory);
		  fileattrs = Ffile_attributes (decoded_fullname, id_format);

		  list = Fcons (Fcons (finalname, fileattrs), list);
		  UNGCPRO;
		}
	      else
		list = Fcons (finalname, list);
	    }

	  UNGCPRO;
	}
    }

  BLOCK_INPUT;
  closedir (d);
  UNBLOCK_INPUT;
#ifdef WINDOWSNT
  if (attrs)
    Vw32_get_true_file_attributes = w32_save;
#endif

  /* Discard the unwind protect.  */
  specpdl_ptr = specpdl + count;

  if (NILP (nosort))
    list = Fsort (Fnreverse (list),
		  attrs ? Qfile_attributes_lessp : Qstring_lessp);

  RETURN_UNGCPRO (list);
}
Example #22
0
int
main(int argc, char *argv[])
{
  char *dot;
  char *mntopts = (char *) NULL;
  char hostpid_fs[MAXHOSTNAMELEN + 1 + 16];	/* room for ":(pid###)" */
  char progpid_fs[PROGNAMESZ + 1 + 11];		/* room for ":pid" */
  char preopts[128];
  char *progname;
  int forcecache = 0;
  int forcefast = 0;
  int genflags = 0;
  int opt, ret;
  int opterrs = 0;
  int retry;
  int soNFS;			/* NFS socket */
  int s = -99;
  mntent_t mnt;
  nfs_args_t nfs_args;
  am_nfs_handle_t anh;
  struct dirent *direntry;
  struct group *grp;
  struct stat stmodes;
  DIR *mountdir;
  MTYPE_TYPE type = MOUNT_TYPE_NFS;

#ifdef HAVE_SIGACTION
  struct sigaction sa;
#endif /* not HAVE_SIGACTION */

#ifndef HAVE_TRANSPORT_TYPE_TLI
  struct sockaddr_in localsocket;
#endif /* not HAVE_TRANSPORT_TYPE_TLI */


  /* get program name and truncate so we don't overflow progpid_fs */

  if ((progname = strrchr(argv[0], '/')) != NULL)
    progname++;
  else
    progname = argv[0];
  if ((int) strlen(progname) > PROGNAMESZ) /* truncate to reasonable size */
    progname[PROGNAMESZ] = '\0';
  am_set_progname(progname);

  while ((opt = getopt(argc, argv, "a:c:CD:fg:hi:l:no:pP:x:v")) != -1)
    switch (opt) {

    case 'a':
      if (!optarg || optarg[0] != '/') {
	printf("%s: invalid directory for -a: %s\n",
	       am_get_progname(), optarg);
	exit(3);
      }
      alt_spooldir = optarg;
      break;

    case 'c':
      if (!atoi(optarg)) {
	printf("%s: invalid interval for -c: %s\n",
	       am_get_progname(), optarg);
	exit(3);
      }
      cache_interval = atoi(optarg);
      break;

    case 'C':
      forcecache++;
      break;

    case 'f':
      forcefast++;
      break;

    case 'g':
      hlfs_group = optarg;
      break;

    case 'i':
      if (!atoi(optarg)) {
	printf("%s: invalid interval for -i: %s\n",
	       am_get_progname(), optarg);
	exit(3);
      }
      reloadinterval.it_interval.tv_sec = atoi(optarg);
      reloadinterval.it_value.tv_sec = atoi(optarg);
      break;

    case 'l':
      logfile = optarg;
      break;

    case 'n':
      noverify++;
      break;

    case 'o':
      mntopts = optarg;
      break;

    case 'p':
      printpid++;
      break;

    case 'P':
      passwdfile = optarg;
      break;

    case 'v':
      fprintf(stderr, "%s\n", HLFSD_VERSION);
      exit(0);

    case 'x':
      opterrs += switch_option(optarg);
      break;

    case 'D':
#ifdef DEBUG
      opterrs += debug_option(optarg);
#else /* not DEBUG */
      fprintf(stderr, "%s: not compiled with DEBUG -- sorry.\n", am_get_progname());
#endif /* not DEBUG */
      break;

    case 'h':
    case '?':
      opterrs++;
    }

  /* set some default debugging options */
  if (xlog_level_init == ~0)
    switch_option("");
  /* need my pid before any dlog/plog */
  am_set_mypid();
#ifdef DEBUG
  switch_option("debug");
#endif /* DEBUG */

/*
 * Terminate if did not ask to forcecache (-C) and hlfsd would not be able
 * to set the minimum cache intervals.
 */
#if !defined(MNT2_NFS_OPT_ACREGMIN) && !defined(MNT2_NFS_OPT_NOAC) && !defined(HAVE_NFS_ARGS_T_ACREGMIN)
  if (!forcecache) {
    fprintf(stderr, "%s: will not be able to turn off attribute caches.\n", am_get_progname());
    exit(1);
  }
#endif /* !defined(MNT2_NFS_OPT_ACREGMIN) && !defined(MNT2_NFS_OPT_NOAC) && !defined(HAVE_NFS_ARGS_T_ACREGMIN) */


  switch (argc - optind) {
  case 2:
    home_subdir = argv[optind + 1];
  case 1:
    dir_name = argv[optind];
  case 0:
    break;
  default:
    opterrs++;
  }

  if (opterrs)
    usage();

  /* ensure that only root can run hlfsd */
  if (geteuid()) {
    fprintf(stderr, "hlfsd can only be run as root\n");
    exit(1);
  }
  setbuf(stdout, (char *) NULL);
  umask(0);

  /* find gid for hlfs_group */
  if ((grp = getgrnam(hlfs_group)) == (struct group *) NULL) {
    fprintf(stderr, "%s: cannot get gid for group \"%s\".\n",
	    am_get_progname(), hlfs_group);
  } else {
    hlfs_gid = grp->gr_gid;
  }

  /* get hostname for logging and open log before we reset umask */
  gethostname(hostname, sizeof(hostname));
  hostname[sizeof(hostname) - 1] = '\0';
  if ((dot = strchr(hostname, '.')) != NULL)
    *dot = '\0';
  orig_umask = umask(0);
  if (logfile)
    switch_to_logfile(logfile, orig_umask);

#if defined(DEBUG) && !defined(MOUNT_TABLE_ON_FILE)
  if (debug_flags & D_MTAB)
    dlog("-D mtab option ignored");
#endif /* defined(DEBUG) && !defined(MOUNT_TABLE_ON_FILE) */

  /* avoid hanging on other NFS servers if started elsewhere */
  if (chdir("/") < 0)
    fatal("cannot chdir to /: %m");

  if (geteuid() != 0)
    fatal("must be root to mount filesystems");

  /*
   * dir_name must match "^(/.*)/([^/]+)$", and is split at last '/' with
   * slinkname = `basename $dir_name` - requires dir_name be writable
   */

  if (dir_name[0] != '/'
      || ((slinkname = strrchr(dir_name, '/')), *slinkname++ = '\0',
	  (dir_name[0] == '\0' || slinkname[0] == '\0'))) {
    if (slinkname)
      *--slinkname = '/';
    printf("%s: invalid mount directory/link %s\n",
	   am_get_progname(), dir_name);
    exit(3);
  }

  clock_valid = 0;		/* invalidate logging clock */

  if (!forcefast) {
    /* make sure mount point exists and is at least mode 555 */
    if (stat(dir_name, &stmodes) < 0)
      if (errno != ENOENT || mkdirs(dir_name, 0555) < 0
	  || stat(dir_name, &stmodes) < 0)
	fatalerror(dir_name);

    if ((stmodes.st_mode & 0555) != 0555) {
      fprintf(stderr, "%s: directory %s not read/executable\n",
	      am_get_progname(), dir_name);
      plog(XLOG_WARNING, "directory %s not read/executable",
	   dir_name);
    }

    /* warn if extraneous stuff will be hidden by mount */
    if ((mountdir = opendir(dir_name)) == NULL)
      fatalerror(dir_name);

    while ((direntry = readdir(mountdir)) != NULL) {
      if (!NSTREQ(".", direntry->d_name, NAMLEN(direntry)) &&
	  !NSTREQ("..", direntry->d_name, NAMLEN(direntry)) &&
	  !NSTREQ(slinkname, direntry->d_name, NAMLEN(direntry)))
	break;
    }

    if (direntry != NULL) {
      fprintf(stderr, "%s: %s/%s will be hidden by mount\n",
	      am_get_progname(), dir_name, direntry->d_name);
      plog(XLOG_WARNING, "%s/%s will be hidden by mount\n",
	   dir_name, direntry->d_name);
    }
    closedir(mountdir);

    /* make sure alternate spool dir exists */
    if ((errno = mkdirs(alt_spooldir, OPEN_SPOOLMODE))) {
      fprintf(stderr, "%s: cannot create alternate dir ",
	      am_get_progname());
      perror(alt_spooldir);
      plog(XLOG_ERROR, "cannot create alternate dir %s: %m",
	   alt_spooldir);
    }
    chmod(alt_spooldir, OPEN_SPOOLMODE);

    /* create failsafe link to alternate spool directory */
    slinkname[-1] = '/';	/* unsplit dir_name to include link */
    if (lstat(dir_name, &stmodes) == 0 &&
	(stmodes.st_mode & S_IFMT) != S_IFLNK) {
      fprintf(stderr, "%s: failsafe %s not a symlink\n",
	      am_get_progname(), dir_name);
      plog(XLOG_WARNING, "failsafe %s not a symlink\n",
	   dir_name);
    } else {
      unlink(dir_name);

      if (symlink(alt_spooldir, dir_name) < 0) {
	fprintf(stderr,
		"%s: cannot create failsafe symlink %s -> ",
		am_get_progname(), dir_name);
	perror(alt_spooldir);
	plog(XLOG_WARNING,
	     "cannot create failsafe symlink %s -> %s: %m",
	     dir_name, alt_spooldir);
      }
    }

    slinkname[-1] = '\0';	/* resplit dir_name */
  } /* end of "if (!forcefast) {" */

  /*
   * Register hlfsd as an nfs service with the portmapper.
   */
#ifdef HAVE_TRANSPORT_TYPE_TLI
  ret = create_nfs_service(&soNFS, &nfs_port, &nfsxprt, nfs_program_2);
#else /* not HAVE_TRANSPORT_TYPE_TLI */
  ret = create_nfs_service(&soNFS, &nfs_port, &nfsxprt, nfs_program_2);
#endif /* not HAVE_TRANSPORT_TYPE_TLI */
  if (ret != 0)
    fatal("cannot create NFS service");

#ifdef HAVE_SIGACTION
  sa.sa_handler = proceed;
  sa.sa_flags = 0;
  sigemptyset(&(sa.sa_mask));
  sigaddset(&(sa.sa_mask), SIGUSR2);
  sigaction(SIGUSR2, &sa, NULL);
#else /* not HAVE_SIGACTION */
  signal(SIGUSR2, proceed);
#endif /* not HAVE_SIGACTION */

  plog(XLOG_INFO, "Initializing hlfsd...");
  hlfsd_init();			/* start up child (forking) to run svc_run */

#ifdef HAVE_SIGACTION
  sa.sa_handler = reaper;
  sa.sa_flags = 0;
  sigemptyset(&(sa.sa_mask));
  sigaddset(&(sa.sa_mask), SIGCHLD);
  sigaction(SIGCHLD, &sa, NULL);
#else /* not HAVE_SIGACTION */
  signal(SIGCHLD, reaper);
#endif /* not HAVE_SIGACTION */

#ifdef DEBUG
  /*
   * In the parent, if -D nodaemon (or -D daemon) , we don't need to
   * set this signal handler.
   */
  amuDebug(D_DAEMON) {
#endif /* DEBUG */
    /* XXX: port to use pure svr4 signals */
    s = -99;
    while (stoplight != SIGUSR2) {
      plog(XLOG_INFO, "parent waits for child to setup (stoplight=%d)", stoplight);
      s = sigpause(0);		/* wait for child to set up */
      sleep(1);
    }
#ifdef DEBUG
  }
#endif /* DEBUG */

  /*
   * setup options to mount table (/etc/{mtab,mnttab}) entry
   */
  sprintf(hostpid_fs, "%s:(pid%d)", hostname, masterpid);
  memset((char *) &mnt, 0, sizeof(mnt));
  mnt.mnt_dir = dir_name;	/* i.e., "/mail" */
  mnt.mnt_fsname = hostpid_fs;
  if (mntopts) {
    mnt.mnt_opts = mntopts;
  } else {
    strcpy(preopts, default_mntopts);
    /*
     * Turn off all kinds of attribute and symlink caches as
     * much as possible.  Also make sure that mount does not
     * show up to df.
     */
#ifdef MNTTAB_OPT_INTR
    strcat(preopts, ",");
    strcat(preopts, MNTTAB_OPT_INTR);
#endif /* MNTTAB_OPT_INTR */
#ifdef MNTTAB_OPT_IGNORE
    strcat(preopts, ",");
    strcat(preopts, MNTTAB_OPT_IGNORE);
#endif /* MNTTAB_OPT_IGNORE */
#ifdef MNT2_GEN_OPT_CACHE
    strcat(preopts, ",nocache");
#endif /* MNT2_GEN_OPT_CACHE */
#ifdef MNT2_NFS_OPT_SYMTTL
    strcat(preopts, ",symttl=0");
#endif /* MNT2_NFS_OPT_SYMTTL */
    mnt.mnt_opts = preopts;
  }

  /*
   * Make sure that amd's top-level NFS mounts are hidden by default
   * from df.
   * If they don't appear to support the either the "ignore" mnttab
   * option entry, or the "auto" one, set the mount type to "nfs".
   */
#ifdef HIDE_MOUNT_TYPE
  mnt.mnt_type = HIDE_MOUNT_TYPE;
#else /* not HIDE_MOUNT_TYPE */
  mnt.mnt_type = "nfs";
#endif /* not HIDE_MOUNT_TYPE */
  /* some systems don't have a mount type, but a mount flag */

#ifndef HAVE_TRANSPORT_TYPE_TLI
  amu_get_myaddress(&localsocket.sin_addr);
  localsocket.sin_family = AF_INET;
  localsocket.sin_port = htons(nfsxprt->xp_port);
#endif /* not HAVE_TRANSPORT_TYPE_TLI */

  /*
   * Update hostname field.
   * Make some name prog:pid (i.e., hlfsd:174) for hostname
   */
  sprintf(progpid_fs, "%s:%d", am_get_progname(), masterpid);

  /* Most kernels have a name length restriction. */
  if ((int) strlen(progpid_fs) >= (int) MAXHOSTNAMELEN)
    strcpy(progpid_fs + MAXHOSTNAMELEN - 3, "..");

  genflags = compute_mount_flags(&mnt);

  retry = hasmntval(&mnt, MNTTAB_OPT_RETRY);
  if (retry <= 0)
    retry = 1;			/* XXX */

  memmove(&anh.v2.fhs_fh, root_fhp, sizeof(*root_fhp));
#ifdef HAVE_TRANSPORT_TYPE_TLI
  compute_nfs_args(&nfs_args,
		   &mnt,
		   genflags,
		   nfsncp,
		   NULL,	/* remote host IP addr is set below */
		   NFS_VERSION,	/* version 2 */
		   "udp",	/* XXX: shouldn't this be "udp"? */
		   &anh,
		   progpid_fs,	/* host name for kernel */
		   hostpid_fs); /* filesystem name for kernel */
  /*
   * IMPORTANT: set the correct IP address AFTERWARDS.  It cannot
   * be done using the normal mechanism of compute_nfs_args(), because
   * that one will allocate a new address and use NFS_SA_DREF() to copy
   * parts to it, while assuming that the ip_addr passed is always
   * a "struct sockaddr_in".  That assumption is incorrect on TLI systems,
   * because they define a special macro HOST_SELF which is DIFFERENT
   * than localhost (127.0.0.1)!
   */
  nfs_args.addr = &nfsxprt->xp_ltaddr;
#else /* not HAVE_TRANSPORT_TYPE_TLI */
  compute_nfs_args(&nfs_args,
		   &mnt,
		   genflags,
		   NULL,
		   &localsocket,
		   NFS_VERSION, /* version 2 */
		   "udp",	/* XXX: shouldn't this be "udp"? */
		   &anh,
		   progpid_fs,	/* host name for kernel */
		   hostpid_fs); /* filesystem name for kernel */
#endif /* not HAVE_TRANSPORT_TYPE_TLI */

  /*************************************************************************
   * NOTE: while compute_nfs_args() works ok for regular NFS mounts	   *
   * the toplvl one is not, and so some options must be corrected by hand  *
   * more carefully, *after* compute_nfs_args() runs.			   *
   *************************************************************************/
  compute_automounter_nfs_args(&nfs_args, &mnt);

  clock_valid = 0;		/* invalidate logging clock */

/*
 * The following code could be cleverly ifdef-ed, but I duplicated the
 * mount_fs call three times for simplicity and readability.
 */
#ifdef DEBUG
/*
 * For some reason, this mount may have to be done in the background, if I am
 * using -D nodebug.  I suspect that the actual act of mounting requires
 * calling to hlfsd itself to invoke one or more of its nfs calls, to stat
 * /mail.  That means that even if you say -D nodaemon, at least the mount
 * of hlfsd itself on top of /mail will be done in the background.
 * The other alternative I have is to run svc_run, but set a special
 * signal handler to perform the mount in N seconds via some alarm.
 *      -Erez Zadok.
 */
  amuDebug(D_DAEMON) {	/* asked for -D daemon */
    plog(XLOG_INFO, "parent NFS mounting hlfsd service points");
    if (mount_fs2(&mnt, dir_name, genflags, (caddr_t) &nfs_args, retry, type, 0, NULL, mnttab_file_name) < 0)
      fatal("nfsmount: %m");
  } else {			/* asked for -D nodaemon */
    if (fork() == 0) {		/* child runs mount */
Example #23
0
File: dlopen.c Project: 1ack/Impala
/* gets the list of mechanisms */
int _sasl_load_plugins(const add_plugin_list_t *entrypoints,
		       const sasl_callback_t *getpath_cb,
		       const sasl_callback_t *verifyfile_cb)
{
    int result;
    const add_plugin_list_t *cur_ep;
#ifdef DO_DLOPEN
    char str[PATH_MAX], tmp[PATH_MAX+2], prefix[PATH_MAX+2];
				/* 1 for '/' 1 for trailing '\0' */
    char c;
    int pos;
    const char *path=NULL;
    int position;
    DIR *dp;
    struct dirent *dir;
#endif
#ifndef PIC
    add_plugin_t *add_plugin;
    _sasl_plug_type type;
    _sasl_plug_rec *p;
#endif

    if (! entrypoints
	|| ! getpath_cb
	|| getpath_cb->id != SASL_CB_GETPATH
	|| ! getpath_cb->proc
	|| ! verifyfile_cb
	|| verifyfile_cb->id != SASL_CB_VERIFYFILE
	|| ! verifyfile_cb->proc)
	return SASL_BADPARAM;

#ifndef PIC
    /* do all the static plugins first */

    for(cur_ep = entrypoints; cur_ep->entryname; cur_ep++) {

	/* What type of plugin are we looking for? */
	if(!strcmp(cur_ep->entryname, "sasl_server_plug_init")) {
	    type = SERVER;
	    add_plugin = (add_plugin_t *)sasl_server_add_plugin;
	} else if (!strcmp(cur_ep->entryname, "sasl_client_plug_init")) {
	    type = CLIENT;
	    add_plugin = (add_plugin_t *)sasl_client_add_plugin;
	} else if (!strcmp(cur_ep->entryname, "sasl_auxprop_plug_init")) {
	    type = AUXPROP;
	    add_plugin = (add_plugin_t *)sasl_auxprop_add_plugin;
	} else if (!strcmp(cur_ep->entryname, "sasl_canonuser_init")) {
	    type = CANONUSER;
	    add_plugin = (add_plugin_t *)sasl_canonuser_add_plugin;
	} else {
	    /* What are we looking for then? */
	    return SASL_FAIL;
	}
	for (p=_sasl_static_plugins; p->type; p++) {
	    if(type == p->type)
	    	result = add_plugin(p->name, p->plug);
	}
    }
#endif /* !PIC */

/* only do the following if:
 * 
 * we support dlopen()
 *  AND we are not staticly compiled
 *      OR we are staticly compiled and TRY_DLOPEN_WHEN_STATIC is defined
 */
#if defined(DO_DLOPEN) && (defined(PIC) || (!defined(PIC) && defined(TRY_DLOPEN_WHEN_STATIC)))
    /* get the path to the plugins */
    result = ((sasl_getpath_t *)(getpath_cb->proc))(getpath_cb->context,
						    &path);
    if (result != SASL_OK) return result;
    if (! path) return SASL_FAIL;

    if (strlen(path) >= PATH_MAX) { /* no you can't buffer overrun */
	return SASL_FAIL;
    }

    position=0;
    do {
	pos=0;
	do {
	    c=path[position];
	    position++;
	    str[pos]=c;
	    pos++;
	} while ((c!=':') && (c!='=') && (c!=0));
	str[pos-1]='\0';

	strcpy(prefix,str);
	strcat(prefix,"/");

	if ((dp=opendir(str)) !=NULL) /* ignore errors */    
	{
	    while ((dir=readdir(dp)) != NULL)
	    {
		size_t length;
		void *library;
		char *c;
		char plugname[PATH_MAX];
		char name[PATH_MAX];

		length = NAMLEN(dir);
		if (length < 4) 
		    continue; /* can not possibly be what we're looking for */

		if (length + pos>=PATH_MAX) continue; /* too big */

		if (strcmp(dir->d_name + (length - strlen(SO_SUFFIX)),
			   SO_SUFFIX)
		    && strcmp(dir->d_name + (length - strlen(LA_SUFFIX)),
			   LA_SUFFIX))
		    continue;

		memcpy(name,dir->d_name,length);
		name[length]='\0';

		result = _parse_la(prefix, name, tmp);
		if(result != SASL_OK)
		    continue;
		
		/* skip "lib" and cut off suffix --
		   this only need be approximate */
		strcpy(plugname, name + 3);
		c = strchr(plugname, (int)'.');
		if(c) *c = '\0';

		result = _sasl_get_plugin(tmp, verifyfile_cb, &library);

		if(result != SASL_OK)
		    continue;

		for(cur_ep = entrypoints; cur_ep->entryname; cur_ep++) {
			_sasl_plugin_load(plugname, library, cur_ep->entryname,
					  cur_ep->add_plugin);
			/* If this fails, it's not the end of the world */
		}
	    }

	    closedir(dp);
	} else {
	    _sasl_log(NULL, SASL_LOG_DEBUG,
		      "looking for plugins in '%s', failed to open directory, error: %s",
		      str,
		      strerror(errno));
	}

    } while ((c!='=') && (c!=0));
#endif /* defined(DO_DLOPEN) && (!defined(PIC) || (defined(PIC) && defined(TRY_DLOPEN_WHEN_STATIC))) */

    return SASL_OK;
}
static void
ScanConflicts(char *path, unsigned inx, int argc, char **argv)
{
    DIR *dp;
    struct dirent *de;
    struct stat sb;
    int j;
    unsigned k;
#if SYS_MSDOS || SYS_OS2 || SYS_WIN32 || SYS_OS2_EMX
    char save_wd[MAXPATHLEN];
#endif

    /*
     * When scanning a directory, we first chdir to it, mostly to make
     * the scan+stat work faster, but also because some systems don't
     * scan properly otherwise.
     *
     * MSDOS and OS/2 are a little more complicated, because each drive
     * has its own current directory.
     */
#if SYS_MSDOS || SYS_OS2 || SYS_WIN32 || SYS_OS2_EMX
    (void) strcpy(save_wd, dot);
    if (!strcmp(".", path)) {
	path = dot;
    } else if (!same_drive(dot, path)) {
	if (!set_drive(path))
	    return;
	getwd(save_wd);
    }
#endif
    if (v_opt > 2)
	printf("ScanConflicts \"%s\"\n", path);

    if (set_directory(path)
	&& (dp = opendir(path)) != NULL) {

	while ((de = readdir(dp)) != NULL) {
	    register
	    type_t ok = 0;
	    int found = FALSE;
	    char buffer[MAXPATHLEN];
	    char *the_name;
	    char *the_NAME;

	    if (do_blips)
		blip('.');

	    (void) sprintf(buffer, "%.*s", (int) NAMLEN(de), de->d_name);
	    the_name = MakeString(DOS_upper(buffer));
	    the_NAME = ToCompare(the_name);

	    /* If arguments are given, restrict search to them */
	    if (argc > optind) {
		for (j = optind; j < argc; j++) {
		    if (SameName(argv[j], the_name)) {
			found = TRUE;
			break;
		    }
		}
		if (!found)
		    continue;
	    }

	    /* Verify that the name is a file, and executable */
	    if (stat(the_name, &sb) < 0)
		continue;
	    if ((sb.st_mode & S_IFMT) != S_IFREG)
		continue;

#if SYS_UNIX || SYS_OS2 || SYS_OS2_EMX
	    if (access(the_name, acc_mask) < 0)
		continue;
	    ok = 1;
#endif
	    if (FileTypes != 0) {
		if ((ok = LookupType(the_name)) == 0)
		    continue;
	    }

	    /* Find the name in our array of all names */
	    found = FALSE;
	    for (k = 0; k < total; k++) {
		if (SameName(inpath[k].ip_NAME, the_NAME)) {
		    FoundNode(&inpath[k], inx);
		    found = TRUE;
		    break;
		}
	    }

	    /* If not there, add it */
	    if (found) {
		if (the_NAME != the_name) {
		    FreeString(the_NAME);
		}
	    } else {
		if (!(total & CHUNK)) {
		    size_t need = (((total * 3) / 2) | CHUNK) + 1;
		    if (inpath != 0)
			inpath = TypeRealloc(INPATH, inpath, need);
		    else
			inpath = TypeAlloc(INPATH, need);
		}
		j = (int) total++;
		inpath[j].ip_name = the_name;
		inpath[j].ip_NAME = the_NAME;
		inpath[j].node = TypeAlloc(NODE, path_len);
		FoundNode(&inpath[j], inx);
	    }
	    if (v_opt > 2) {
		(void) printf("%c %s%c%s\n",
			      found ? '+' : '*',
			      path, PATHNAME_SEP, buffer);
	    }
	}
	(void) closedir(dp);
    }
#if SYS_MSDOS || SYS_OS2 || SYS_WIN32 || SYS_OS2_EMX
    if (strcmp(dot, save_wd)) {
	chdir(save_wd);
    }
#endif
    (void) set_directory(dot);
}
Example #25
0
sqInt dir_Lookup(char *pathString, sqInt pathStringLength, sqInt index,
/* outputs: */  char *name, sqInt *nameLength, sqInt *creationDate, sqInt *modificationDate,
		sqInt *isDirectory, squeakFileOffsetType *sizeIfFile)
#endif
{
  /* Lookup the index-th entry of the directory with the given path, starting
     at the root of the file system. Set the name, name length, creation date,
     creation time, directory flag, and file size (if the entry is a file).
     Return:	0 	if a entry is found at the given index
     		1	if the directory has fewer than index entries
		2	if the given path has bad syntax or does not reach a directory
  */

  int i;
  int nameLen= 0;
  struct dirent *dirEntry= 0;
  char unixPath[MAXPATHLEN+1];
  struct stat statBuf;

  /* default return values */
  *name             = 0;
  *nameLength       = 0;
  *creationDate     = 0;
  *modificationDate = 0;
  *isDirectory      = false;
  *sizeIfFile       = 0;
#if PharoVM
  *posixPermissions = 0;
  *isSymlink        = false;
#endif

  if ((pathStringLength == 0))
    strcpy(unixPath, ".");
  else if (!sq2uxPath(pathString, pathStringLength, unixPath, MAXPATHLEN, 1))
    return BAD_PATH;

  /* get file or directory info */
  if (!maybeOpenDir(unixPath))
    return BAD_PATH;

  if (++lastIndex == index)
    index= 1;		/* fake that the dir is rewound and we want the first entry */
  else
    {
      rewinddir(openDir);	/* really rewind it, and read to the index */
      lastIndex= index;
    }

  for (i= 0; i < index; i++)
    {
    nextEntry:
      do
	{ 
	  errno= 0; 
	  dirEntry= readdir(openDir);
	}
      while ((dirEntry == 0) && (errno == EINTR));

      if (!dirEntry)
	return NO_MORE_ENTRIES;
      
      nameLen= NAMLEN(dirEntry);

      /* ignore '.' and '..' (these are not *guaranteed* to be first) */
      if (nameLen < 3 && dirEntry->d_name[0] == '.')
	if (nameLen == 1 || dirEntry->d_name[1] == '.')
	  goto nextEntry;
    }

  *nameLength= ux2sqPath(dirEntry->d_name, nameLen, name, MAXPATHLEN, 0);

  {
    char terminatedName[MAXPATHLEN+1];
    if(nameLen > MAXPATHLEN)
      return BAD_PATH;
    strncpy(terminatedName, dirEntry->d_name, nameLen);
    terminatedName[nameLen]= '\0';
    if(strlen(unixPath) + 1 + nameLen > MAXPATHLEN)
      return BAD_PATH;
    strcat(unixPath, "/");
    strcat(unixPath, terminatedName);
    if (stat(unixPath, &statBuf) && lstat(unixPath, &statBuf))
    {
	/* We can't stat the entry, but failing here would invalidate
	   the whole directory --bertf */
      return ENTRY_FOUND;
    }
  }

  /* last change time */
  *creationDate= convertToSqueakTime(statBuf.st_ctime);
  /* modification time */
  *modificationDate= convertToSqueakTime(statBuf.st_mtime);

  if (S_ISDIR(statBuf.st_mode))
    *isDirectory= true;
  else
    *sizeIfFile= statBuf.st_size;

#if PharoVM
  *isSymlink = S_ISLNK(statBuf.st_mode);
  *posixPermissions = statBuf.st_mode & 0777;
#endif

  return ENTRY_FOUND;
}
Example #26
0
static int
typelist(int eargc, char *eargv[],
	 bool verbosity,
	 void (*hook) (const char *, TERMTYPE *tp))
/* apply a function to each entry in given terminfo directories */
{
    int i;

    for (i = 0; i < eargc; i++) {
#if USE_DATABASE
	if (_nc_is_dir_path(eargv[i])) {
	    char *cwd_buf = 0;
	    DIR *termdir;
	    DIRENT *subdir;

	    if ((termdir = opendir(eargv[i])) == 0) {
		(void) fflush(stdout);
		(void) fprintf(stderr,
			       "%s: can't open terminfo directory %s\n",
			       _nc_progname, eargv[i]);
		return (EXIT_FAILURE);
	    } else if (verbosity)
		(void) printf("#\n#%s:\n#\n", eargv[i]);

	    while ((subdir = readdir(termdir)) != 0) {
		size_t len = NAMLEN(subdir);
		size_t cwd_len = len + strlen(eargv[i]) + 3;
		char name_1[PATH_MAX];
		DIR *entrydir;
		DIRENT *entry;

		cwd_buf = typeRealloc(char, cwd_len, cwd_buf);
		if (cwd_buf == 0)
		    failed("realloc cwd_buf");

		assert(cwd_buf != 0);

		strncpy(name_1, subdir->d_name, len)[len] = '\0';
		if (isDotname(name_1))
		    continue;

		(void) sprintf(cwd_buf, "%s/%.*s/", eargv[i], (int) len, name_1);
		if (chdir(cwd_buf) != 0)
		    continue;

		entrydir = opendir(".");
		if (entrydir == 0) {
		    perror(cwd_buf);
		    continue;
		}
		while ((entry = readdir(entrydir)) != 0) {
		    char name_2[PATH_MAX];
		    TERMTYPE lterm;
		    char *cn;
		    int status;

		    len = NAMLEN(entry);
		    strncpy(name_2, entry->d_name, len)[len] = '\0';
		    if (isDotname(name_2) || !_nc_is_file_path(name_2))
			continue;

		    status = _nc_read_file_entry(name_2, &lterm);
		    if (status <= 0) {
			(void) fflush(stdout);
			(void) fprintf(stderr,
				       "%s: couldn't open terminfo file %s.\n",
				       _nc_progname, name_2);
			return (EXIT_FAILURE);
		    }

		    /* only visit things once, by primary name */
		    cn = _nc_first_name(lterm.term_names);
		    if (!strcmp(cn, name_2)) {
			/* apply the selected hook function */
			(*hook) (cn, &lterm);
		    }
		    _nc_free_termtype(&lterm);
		}
		closedir(entrydir);
	    }
	    closedir(termdir);
	    if (cwd_buf != 0)
		free(cwd_buf);
	}
#if USE_HASHED_DB
	else {
	    DB *capdbp;
	    char filename[PATH_MAX];

	    if (make_db_name(filename, eargv[i], sizeof(filename))) {
		if ((capdbp = _nc_db_open(filename, FALSE)) != 0) {
		    DBT key, data;
		    int code;

		    code = _nc_db_first(capdbp, &key, &data);
		    while (code == 0) {
			TERMTYPE lterm;
			int used;
			char *have;
			char *cn;

			if (_nc_db_have_data(&key, &data, &have, &used)) {
			    if (_nc_read_termtype(&lterm, have, used) > 0) {
				/* only visit things once, by primary name */
				cn = _nc_first_name(lterm.term_names);
				/* apply the selected hook function */
				(*hook) (cn, &lterm);
				_nc_free_termtype(&lterm);
			    }
			}
			code = _nc_db_next(capdbp, &key, &data);
		    }

		    _nc_db_close(capdbp);
		}
	    }
	}
#endif
#endif
#if USE_TERMCAP
#if HAVE_BSD_CGETENT
	char *db_array[2];
	char *buffer = 0;

	if (verbosity)
	    (void) printf("#\n#%s:\n#\n", eargv[i]);

	db_array[0] = eargv[i];
	db_array[1] = 0;

	if (cgetfirst(&buffer, db_array)) {
	    show_termcap(buffer, hook);
	    free(buffer);
	    while (cgetnext(&buffer, db_array)) {
		show_termcap(buffer, hook);
		free(buffer);
	    }
	}
	cgetclose();
#else
	/* scan termcap text-file only */
	if (_nc_is_file_path(eargv[i])) {
	    char buffer[2048];
	    FILE *fp;

	    if ((fp = fopen(eargv[i], "r")) != 0) {
		while (fgets(buffer, sizeof(buffer), fp) != 0) {
		    if (*buffer == '#')
			continue;
		    if (isspace(*buffer))
			continue;
		    show_termcap(buffer, hook);
		}
		fclose(fp);
	    }
	}
#endif
#endif
    }
Example #27
0
static void filedb_update(char *path, FILE * f, int sort)
{
  struct dirent *dd;
  DIR *dir;
  filedb fdb[2];
  char name[61];
  long where, oldwhere;
  struct stat st;
  char s[512];
  int ret;

  /* FIRST: make sure every real file is in the database */
  dir = opendir(path);
  if (dir == NULL) {
    putlog(LOG_MISC, "*", FILES_NOUPDATE);
    return;
  }
  dd = readdir(dir);
  while (dd != NULL) {
    strncpy(name, dd->d_name, 60);
    name[60] = 0;
    if (NAMLEN(dd) <= 60)
      name[NAMLEN(dd)] = 0;
    else {
      /* truncate name on disk */
      char s1[512], s2[256];

      strcpy(s1, path);
      strcat(s1, "/");
      strncat(s1, dd->d_name, NAMLEN(dd));
      s1[strlen(path) + NAMLEN(dd) + 1] = 0;
      sprintf(s2, "%s/%s", path, name);
      movefile(s1, s2);
    }
    if (name[0] != '.') {
      sprintf(s, "%s/%s", path, name);
      stat(s, &st);
      where = 0;
      ret = findmatch(f, name, &where, &fdb[0]);
      if (!ret) {
	/* new file! */
	where = findempty(f);
	fseek(f, where, SEEK_SET);
	fdb[0].version = FILEVERSION;
	fdb[0].stat = 0;	/* by default, visible regular file */
	strcpy(fdb[0].filename, name);
	fdb[0].desc[0] = 0;
	strcpy(fdb[0].uploader, botnetnick);
	fdb[0].gots = 0;
	fdb[0].flags_req[0] = 0;
	fdb[0].uploaded = now;
	fdb[0].size = st.st_size;
	fdb[0].sharelink[0] = 0;
	if (S_ISDIR(st.st_mode))
	  fdb[0].stat |= FILE_DIR;
	fwrite(&fdb[0], sizeof(filedb), 1, f);
      } else if (fdb[0].version < FILEVERSION) {
	/* old version filedb, do the dirty */
	if (fdb[0].version == FILEVERSION_OLD) {
	  filedb_old *fdbo = (filedb_old *) & fdb[0];

	  fdb[0].desc[185] = 0;	/* truncate it */
	  fdb[0].chname[0] = 0;	/* new entry */
	  strcpy(fdb[0].uploader, fdbo->uploader);	/* moved forward
							 * a few bytes */
	  strcpy(fdb[0].flags_req, fdbo->flags_req);	/* and again */
	  fdb[0].version = FILEVERSION;
	  fdb[0].size = st.st_size;
	  fseek(f, where, SEEK_SET);
	  fwrite(&fdb[0], sizeof(filedb), 1, f);
	} else {
	  putlog(LOG_MISC, "*", "!!! Unknown filedb type !");
	}
      } else {
	/* update size if needed */
	fdb[0].size = st.st_size;
	fseek(f, where, SEEK_SET);
	fwrite(&fdb[0], sizeof(filedb), 1, f);
      }
    }
    dd = readdir(dir);
  }
  closedir(dir);
  /* SECOND: make sure every db file is real, and sort as we go,
   * if we're sorting */
  rewind(f);
  while (!feof(f)) {
    where = ftell(f);
    fread(&fdb[0], sizeof(filedb), 1, f);
    if (!feof(f)) {
      if (!(fdb[0].stat & FILE_UNUSED) && !fdb[0].sharelink[0]) {
	sprintf(s, "%s/%s", path, fdb[0].filename);
	if (stat(s, &st) != 0) {
	  /* gone file */
	  fseek(f, where, SEEK_SET);
	  fdb[0].stat |= FILE_UNUSED;
	  fwrite(&fdb[0], sizeof(filedb), 1, f);
	  /* sunos and others will puke bloody chunks if you write the
	   * last record in a file and then attempt to read to EOF: */
	  fseek(f, where, SEEK_SET);
	  continue;		/* cycle to next one */
	}
      }
      if (sort && !(fdb[0].stat & FILE_UNUSED)) {
	rewind(f);
	oldwhere = ftell(f);
	ret = 0;
	while (!feof(f) && (oldwhere < where)) {
	  fread(&fdb[1 - ret], sizeof(filedb), 1, f);
	  if (!feof(f)) {
	    if ((fdb[0].stat & FILE_UNUSED) ||
		(strcasecmp(fdb[ret].filename,
			    fdb[1 - ret].filename) < 0)) {
	      /* our current is < the checked one, insert here */
	      fseek(f, oldwhere, SEEK_SET);
	      fwrite(&fdb[ret], sizeof(filedb), 1, f);
	      ret = 1 - ret;
	      /* and fall out */
	    }
	    /* otherwise read next entry */
	    oldwhere = ftell(f);
	  }
	}
	/* here, either we've found a place to insert, or got to
	 * the end of the list */
	/* if we've got to the end of the current list oldwhere == where
	 * so we fall through ret will point to the current valid one */
	while (!feof(f) && (oldwhere < where)) {
	  /* need to move this entry up 1 .. */
	  fread(&fdb[1 - ret], sizeof(filedb), 1, f);
	  oldwhere = ftell(f);
	  /* write lower record here */
	  fseek(f, oldwhere, SEEK_SET);
	  fwrite(&fdb[ret], sizeof(filedb), 1, f);
	  ret = 1 - ret;
	}
	/* when we get here fdb[ret] holds the last record,
	 * which needs  to be written where we first grabbed the
	 * record from */
	fseek(f, where, SEEK_SET);
	fwrite(&fdb[ret], sizeof(filedb), 1, f);
      }
    }
  }
  /* write new timestamp */
  filedb_timestamp(f);
}
Example #28
0
/* HandleInputLine is NOT thread safe - due to readdir issues,
   resolving them portably is not really simple. */
static int HandleInputLine(
    int argc,
    char **argv,
    FILE * out)
{
#if defined(HAVE_OPENDIR) && defined (HAVE_READDIR)
    DIR      *curdir;   /* to read current dir with ls */
    struct dirent *dent;
#endif

    /* Reset errno to 0 before we start.
     */
    if (RemoteMode) {
        if (argc > 1 && strcmp("quit", argv[1]) == 0) {
            if (argc != 2) {
                printf("ERROR: invalid parameter count for quit\n");
                return (1);
            }
            exit(0);
        }
#if defined(HAVE_OPENDIR) && defined(HAVE_READDIR) && defined(HAVE_CHDIR) && defined(HAVE_SYS_STAT_H)
        if (argc > 1 && strcmp("cd", argv[1]) == 0) {
            if (argc != 3) {
                printf("ERROR: invalid parameter count for cd\n");
                return (1);
            }
#if ! defined(HAVE_CHROOT) && defined(HAVE_GETUID)
            if (getuid() == 0 && !ChangeRoot) {
                printf
                    ("ERROR: chdir security problem - rrdtool is running as "
                     "root but not chroot!\n");
                return (1);
            }
#endif
            if (chdir(argv[2]) != 0){
                printf("ERROR: chdir %s %s\n", argv[2], rrd_strerror(errno));
                return (1);
            }
            return (0);
        }
        if (argc > 1 && strcmp("pwd", argv[1]) == 0) {
            char     *cwd;      /* To hold current working dir on call to pwd */
            if (argc != 2) {
                printf("ERROR: invalid parameter count for pwd\n");
                return (1);
            }
#ifdef MAXPATH
            cwd = getcwd(NULL, MAXPATH);
#elif defined(HAVE_GET_CURRENT_DIR_NAME)
            cwd = get_current_dir_name();
#else
#error "You must have either MAXPATH or get_current_dir_name()"
#endif
            if (cwd == NULL) {
                printf("ERROR: getcwd %s\n", rrd_strerror(errno));
                return (1);
            }
            printf("%s\n", cwd);
            free(cwd);
            return (0);
        }
        if (argc > 1 && strcmp("mkdir", argv[1]) == 0) {
            if (argc != 3) {
                printf("ERROR: invalid parameter count for mkdir\n");
                return (1);
            }
#if ! defined(HAVE_CHROOT) && defined(HAVE_GETUID)
            if (getuid() == 0 && !ChangeRoot) {
                printf
                    ("ERROR: mkdir security problem - rrdtool is running as "
                     "root but not chroot!\n");
                return (1);
            }
#endif
            if(mkdir(argv[2], 0777)!=0){
                printf("ERROR: mkdir %s: %s\n", argv[2],rrd_strerror(errno));
                return (1);
            }
            return (0);
        }
        if (argc > 1 && strcmp("ls", argv[1]) == 0) {
            if (argc != 2) {
                printf("ERROR: invalid parameter count for ls\n");
                return (1);
            }
            if ((curdir = opendir(".")) != NULL) {
                struct stat st;
                while ((dent = readdir(curdir)) != NULL) {
                    if (!stat(dent->d_name, &st)) {
                        if (S_ISDIR(st.st_mode)) {
                            printf("d %s\n", dent->d_name);
                        }
                        if (strlen(dent->d_name) > 4 && S_ISREG(st.st_mode)) {
                            if (!strcmp
                                (dent->d_name + NAMLEN(dent) - 4, ".rrd")
                                || !strcmp(dent->d_name + NAMLEN(dent) - 4,
                                           ".RRD")) {
                                printf("- %s\n", dent->d_name);
                            }
                        }
                    }
                }
                closedir(curdir);
            } else {
                printf("ERROR: opendir .: %s\n", rrd_strerror(errno));
                return (errno);
            }
            return (0);
        }
#endif                          /* opendir and readdir */

    }
    if (argc < 3
        || strcmp("help", argv[1]) == 0
        || strcmp("--help", argv[1]) == 0
        || strcmp("-help", argv[1]) == 0
        || strcmp("-?", argv[1]) == 0 || strcmp("-h", argv[1]) == 0) {
        PrintUsage("");
        return 0;
    }

    if (strcmp("create", argv[1]) == 0)
        rrd_create(argc - 1, &argv[1]);
    else if (strcmp("dump", argv[1]) == 0)
        rrd_dump(argc - 1, &argv[1]);
    else if (strcmp("info", argv[1]) == 0 || strcmp("updatev", argv[1]) == 0) {
        rrd_info_t *data;

        if (strcmp("info", argv[1]) == 0)

            data = rrd_info(argc - 1, &argv[1]);
        else
            data = rrd_update_v(argc - 1, &argv[1]);
        rrd_info_print(data);
        rrd_info_free(data);
    }
    else if (strcmp("list", argv[1]) == 0) {
        char *list;
        list = rrd_list(argc - 1, &argv[1]);

	if (list) {
	  printf("%s", list);
	  free(list);
	}
    }
    else if (strcmp("--version", argv[1]) == 0 ||
             strcmp("version", argv[1]) == 0 ||
             strcmp("v", argv[1]) == 0 ||
             strcmp("-v", argv[1]) == 0 || strcmp("-version", argv[1]) == 0)
        printf("RRDtool " PACKAGE_VERSION
               "  Copyright by Tobi Oetiker (%f)\n",
               rrd_version());
    else if (strcmp("restore", argv[1]) == 0)
#ifdef HAVE_RRD_RESTORE
        rrd_restore(argc - 1, &argv[1]);
#else
	rrd_set_error("the instance of rrdtool has been compiled without XML import functions");
#endif
    else if (strcmp("resize", argv[1]) == 0)
Example #29
0
/* HandleInputLine is NOT thread safe - due to readdir issues,
   resolving them portably is not really simple. */
int HandleInputLine(
    int argc,
    char **argv,
    FILE * out)
{
#if defined(HAVE_OPENDIR) && defined (HAVE_READDIR)
    DIR      *curdir;   /* to read current dir with ls */
    struct dirent *dent;
#endif

    /* Reset errno to 0 before we start.
     */
    if (RemoteMode) {
        if (argc > 1 && strcmp("quit", argv[1]) == 0) {
            if (argc != 2) {
                printf("ERROR: invalid parameter count for quit\n");
                return (1);
            }
            exit(0);
        }
#if defined(HAVE_OPENDIR) && defined(HAVE_READDIR) && defined(HAVE_CHDIR) && defined(HAVE_SYS_STAT_H)
        if (argc > 1 && strcmp("cd", argv[1]) == 0) {
            if (argc != 3) {
                printf("ERROR: invalid parameter count for cd\n");
                return (1);
            }
#if ! defined(HAVE_CHROOT) || ! defined(HAVE_GETUID)
            if (getuid() == 0 && !ChangeRoot) {
                printf
                    ("ERROR: chdir security problem - rrdtool is running as "
                     "root but not chroot!\n");
                return (1);
            }
#endif
            if (chdir(argv[2]) != 0){
                printf("ERROR: chdir %s %s\n", argv[2], rrd_strerror(errno));
                return (1);
            }
            return (0);
        }
        if (argc > 1 && strcmp("pwd", argv[1]) == 0) {
            char     *cwd;      /* To hold current working dir on call to pwd */
            if (argc != 2) {
                printf("ERROR: invalid parameter count for pwd\n");
                return (1);
            }
            cwd = getcwd(NULL, MAXPATH);
            if (cwd == NULL) {
                printf("ERROR: getcwd %s\n", rrd_strerror(errno));
                return (1);
            }
            printf("%s\n", cwd);
            free(cwd);
            return (0);
        }
        if (argc > 1 && strcmp("mkdir", argv[1]) == 0) {
            if (argc != 3) {
                printf("ERROR: invalid parameter count for mkdir\n");
                return (1);
            }
#if ! defined(HAVE_CHROOT) || ! defined(HAVE_GETUID)
            if (getuid() == 0 && !ChangeRoot) {
                printf
                    ("ERROR: mkdir security problem - rrdtool is running as "
                     "root but not chroot!\n");
                return (1);
            }
#endif
            if(mkdir(argv[2], 0777)!=0){
                printf("ERROR: mkdir %s: %s\n", argv[2],rrd_strerror(errno));
                return (1);
            }
            return (0);
        }
        if (argc > 1 && strcmp("ls", argv[1]) == 0) {
            if (argc != 2) {
                printf("ERROR: invalid parameter count for ls\n");
                return (1);
            }
            if ((curdir = opendir(".")) != NULL) {
                struct stat st;
                while ((dent = readdir(curdir)) != NULL) {
                    if (!stat(dent->d_name, &st)) {
                        if (S_ISDIR(st.st_mode)) {
                            printf("d %s\n", dent->d_name);
                        }
                        if (strlen(dent->d_name) > 4 && S_ISREG(st.st_mode)) {
                            if (!strcmp
                                (dent->d_name + NAMLEN(dent) - 4, ".rrd")
                                || !strcmp(dent->d_name + NAMLEN(dent) - 4,
                                           ".RRD")) {
                                printf("- %s\n", dent->d_name);
                            }
                        }
                    }
                }
                closedir(curdir);
            } else {
                printf("ERROR: opendir .: %s\n", rrd_strerror(errno));
                return (errno);
            }
            return (0);
        }
#endif                          /* opendir and readdir */

    }
    if (argc < 3
        || strcmp("help", argv[1]) == 0
        || strcmp("--help", argv[1]) == 0
        || strcmp("-help", argv[1]) == 0
        || strcmp("-?", argv[1]) == 0 || strcmp("-h", argv[1]) == 0) {
        PrintUsage("");
        return 0;
    }

    if (strcmp("create", argv[1]) == 0)
        rrd_create(argc - 1, &argv[1]);
    else if (strcmp("dump", argv[1]) == 0)
        rrd_dump(argc - 1, &argv[1]);
    else if (strcmp("info", argv[1]) == 0 || strcmp("updatev", argv[1]) == 0) {
        rrd_info_t *data;

        if (strcmp("info", argv[1]) == 0)

            data = rrd_info(argc - 1, &argv[1]);
        else
            data = rrd_update_v(argc - 1, &argv[1]);
        rrd_info_print(data);
        rrd_info_free(data);
    }

    else if (strcmp("--version", argv[1]) == 0 ||
             strcmp("version", argv[1]) == 0 ||
             strcmp("v", argv[1]) == 0 ||
             strcmp("-v", argv[1]) == 0 || strcmp("-version", argv[1]) == 0)
        printf("RRDtool " PACKAGE_VERSION
               "  Copyright by Tobi Oetiker, 1997-2008 (%f)\n",
               rrd_version());
    else if (strcmp("restore", argv[1]) == 0)
        rrd_restore(argc - 1, &argv[1]);
    else if (strcmp("resize", argv[1]) == 0)
        rrd_resize(argc - 1, &argv[1]);
    else if (strcmp("last", argv[1]) == 0)
        printf("%ld\n", rrd_last(argc - 1, &argv[1]));
    else if (strcmp("lastupdate", argv[1]) == 0) {
        rrd_lastupdate(argc - 1, &argv[1]);
    } else if (strcmp("first", argv[1]) == 0)
        printf("%ld\n", rrd_first(argc - 1, &argv[1]));
    else if (strcmp("update", argv[1]) == 0)
        rrd_update(argc - 1, &argv[1]);
    else if (strcmp("fetch", argv[1]) == 0) {
        time_t    start, end, ti;
        unsigned long step, ds_cnt, i, ii;
        rrd_value_t *data, *datai;
        char    **ds_namv;

        if (rrd_fetch
            (argc - 1, &argv[1], &start, &end, &step, &ds_cnt, &ds_namv,
             &data) == 0) {
            datai = data;
            printf("           ");
            for (i = 0; i < ds_cnt; i++)
                printf("%20s", ds_namv[i]);
            printf("\n\n");
            for (ti = start + step; ti <= end; ti += step) {
                printf("%10lu:", ti);
                for (ii = 0; ii < ds_cnt; ii++)
                    printf(" %0.10e", *(datai++));
                printf("\n");
            }
            for (i = 0; i < ds_cnt; i++)
                free(ds_namv[i]);
            free(ds_namv);
            free(data);
        }
    } else if (strcmp("xport", argv[1]) == 0) {
#ifdef HAVE_RRD_GRAPH
      time_t    start, end;
      unsigned long step, col_cnt;
      rrd_value_t *data;
      char    **legend_v;
      rrd_xport
	(argc - 1, &argv[1], NULL, &start, &end, &step, &col_cnt,
	 &legend_v, &data);
#else
        rrd_set_error("the instance of rrdtool has been compiled without graphics");
#endif
    } else if (strcmp("graph", argv[1]) == 0) {
#ifdef HAVE_RRD_GRAPH
        char    **calcpr;

#ifdef notused /*XXX*/
        const char *imgfile = argv[2];  /* rrd_graph changes argv pointer */
#endif
        int       xsize, ysize;
        double    ymin, ymax;
        int       i;
        int       tostdout = (strcmp(argv[2], "-") == 0);
        int       imginfo = 0;

        for (i = 2; i < argc; i++) {
            if (strcmp(argv[i], "--imginfo") == 0
                || strcmp(argv[i], "-f") == 0) {
                imginfo = 1;
                break;
            }
        }
        if (rrd_graph
            (argc - 1, &argv[1], &calcpr, &xsize, &ysize, NULL, &ymin,
             &ymax) == 0) {
            if (!tostdout && !imginfo)
                printf("%dx%d\n", xsize, ysize);
            if (calcpr) {
                for (i = 0; calcpr[i]; i++) {
                    if (!tostdout)
                        printf("%s\n", calcpr[i]);
                    free(calcpr[i]);
                }
                free(calcpr);
            }
        }

#else
       rrd_set_error("the instance of rrdtool has been compiled without graphics");
#endif
    } else if (strcmp("graphv", argv[1]) == 0) {
#ifdef HAVE_RRD_GRAPH
        rrd_info_t *grinfo = NULL;  /* 1 to distinguish it from the NULL that rrd_graph sends in */

        grinfo = rrd_graph_v(argc - 1, &argv[1]);
        if (grinfo) {
            rrd_info_print(grinfo);
            rrd_info_free(grinfo);
        }
#else
       rrd_set_error("the instance of rrdtool has been compiled without graphics");
#endif
    } else if (strcmp("tune", argv[1]) == 0)
        rrd_tune(argc - 1, &argv[1]);
    else if (strcmp("flushcached", argv[1]) == 0)
        rrd_flushcached(argc - 1, &argv[1]);
    else if (strcmp("modify", argv[1]) == 0)
        rrd_modify(argc - 1, &argv[1]);
    else {
        rrd_set_error("unknown function '%s'", argv[1]);
    }
    if (rrd_test_error()) {
        fprintf(out, "ERROR: %s\n", rrd_get_error());
        rrd_clear_error();
        return 1;
    }
    return (0);
}
Example #30
0
sqInt dir_Lookup(char *pathString, sqInt pathStringLength, sqInt index,
/* outputs: */  char *name, sqInt *nameLength, sqInt *creationDate, sqInt *modificationDate,
		sqInt *isDirectory, squeakFileOffsetType *sizeIfFile)
{
  /* Lookup the index-th entry of the directory with the given path, starting
     at the root of the file system. Set the name, name length, creation date,
     creation time, directory flag, and file size (if the entry is a file).
     Return:	0 	if a entry is found at the given index
     		1	if the directory has fewer than index entries
		2	if the given path has bad syntax or does not reach a directory
  */

  int i;
  int nameLen= 0;
  struct dirent *dirEntry= 0;
  char unixPath[DOCUMENT_NAME_SIZE+1];
  struct stat statBuf;

  /* default return values */
  *name             = 0;
  *nameLength       = 0;
  *creationDate     = 0;
  *modificationDate = 0;
  *isDirectory      = false;
  *sizeIfFile       = 0;

  if ((pathStringLength == 0))
    strcpy(unixPath, ".");
  else  {
	if (!ioFilenamefromStringofLengthresolveAliasesRetry(unixPath, pathString,pathStringLength, true, true))
		return BAD_PATH;
	}

  /* get file or directory info */
  if (!maybeOpenDir(unixPath))
    return BAD_PATH;

  if (++lastIndex == index)
    index= 1;		/* fake that the dir is rewound and we want the first entry */
  else
    {
      rewinddir(openDir);	/* really rewind it, and read to the index */
      lastIndex= index;
    }

  for (i= 0; i < index; i++)
    {
    nextEntry:
      do
	{ 
	  errno= 0; 
	  dirEntry= readdir(openDir);
	}
      while ((dirEntry == 0) && (errno == EINTR));

      if (!dirEntry)
	return NO_MORE_ENTRIES;
      
      nameLen= NAMLEN(dirEntry);

      /* ignore '.' and '..' (these are not *guaranteed* to be first) */
      if (nameLen < 3 && dirEntry->d_name[0] == '.')
	if (nameLen == 1 || dirEntry->d_name[1] == '.')
	  goto nextEntry;
    }

  *nameLength= ux2sqPath(dirEntry->d_name, nameLen, name, 256, 0);

  {
    char terminatedName[DOCUMENT_NAME_SIZE+1];
    strncpy(terminatedName, dirEntry->d_name, nameLen);
    terminatedName[nameLen]= '\0';
    strcat(unixPath, "/");
    strcat(unixPath, terminatedName);
    if (stat(unixPath, &statBuf) && lstat(unixPath, &statBuf))
      {
	/* We can't stat the entry, but failing here would invalidate
	   the whole directory --bertf */
	return ENTRY_FOUND;
      }
  }

  /* last change time */
  *creationDate= convertToSqueakTime(statBuf.st_ctime);
  /* modification time */
  *modificationDate= convertToSqueakTime(statBuf.st_mtime);
	{
		FSRef targetFSRef;
		Boolean	targetIsFolder,wasAliased;
		OSErr err;
		
		err = getFSRef(unixPath,&targetFSRef,kCFStringEncodingUTF8);
		if (!err) {
			FSResolveAliasFileWithMountFlags(&targetFSRef,true,&targetIsFolder,&wasAliased,kResolveAliasFileNoUI);
			if (wasAliased && targetIsFolder) {
				*isDirectory= true;
				return ENTRY_FOUND;
			}
		}
	}
  if (S_ISDIR(statBuf.st_mode))
    *isDirectory= true;
  else
    *sizeIfFile= statBuf.st_size;

  return ENTRY_FOUND;
}