コード例 #1
0
ファイル: menu_dir.c プロジェクト: timburrow/ovj3
/************************************************************************
*									*
* The path passed in is scanned via readdir().  For each file in the	*
* path, a menu item is created and inserted into a new menu.  That	*
* new menu is made the PULLRIGHT_MENU of a newly created panel item	*
* for the path item originally passed it.  Since this routine is	*
* recursive, a new menu is created for each subdirectory under the	*
* original path.							*
*									*/
static Menu_item
add_path_to_menu(char *path, u_long addr_notify)
{
   struct stat         s_buf;		/* file status */
   Menu_item           mi;		/* menu item for pullright */
   Menu                next_menu;	/* newly created menu */
   char                buf[MAXPATHLEN];	/* temporary buffer for filename */
   static int          recursion;	/* number of depth */
   char *fname;
   char *pc;

   /* don't add a folder to the list if user can't read it */
   if (stat(path, &s_buf) == -1 || !(s_buf.st_mode & S_IREAD))
      return NULL;

   if (s_buf.st_mode & S_IFDIR)
   {
      int cnt = 0;
      int len;

      /* Only created pullright menu as necessary.  Hence return it */
      if (recursion)
         return (Menu_item)-1;
      recursion++;

      // Get an alphabetized list of the directory contents
      char **contents = get_dir_contents(path);

      /* don't bother adding to list if we can't scan it */
      if ( ! contents ){
	  return NULL;
      }

      next_menu = (Menu)xv_create(XV_NULL, MENU, NULL);

      /* For each file, append it to the menu.  If it is a directory  	*/
      /* append a pullright arrow.  It is is unreadable file, make it 	*/
      /* inactive.							*/
      char **dp;
      for (dp=contents; *dp; dp++){
         if (strcmp(*dp, ".") && strcmp(*dp, "..")){
            (void) sprintf(buf, "%s/%s", path, *dp);
            mi = add_path_to_menu(buf, addr_notify);

            if (!mi || mi == (Menu_item)-1)
	    {
               int do_gen_pullright = (mi == (Menu_item)-1);

               mi = (Menu_item)xv_create(XV_NULL, MENUITEM,
                        MENU_STRING, getfilename(*dp),
                        MENU_RELEASE,
                        MENU_RELEASE_IMAGE,
            		MENU_NOTIFY_PROC,   my_action_proc,
	    		XV_KEY_DATA,	KEY_ADDR_DATA, addr_notify,
                        NULL);

               if (do_gen_pullright)
	          /* Append a pullright arrow and deactivate NOTIFY_PROC */ 
                  xv_set(mi, MENU_GEN_PULLRIGHT, gen_pullright,
				MENU_NOTIFY_PROC,	NULL,
			NULL);
               else
                  /* unreadable file or dir - deactivate item */
                  xv_set(mi, MENU_INACTIVE, TRUE, NULL);
	    }
            xv_set(next_menu, MENU_APPEND_ITEM, mi, NULL);
            cnt++;
         }
	 free(*dp);	// Free filename memory
      }
      free((char *)contents);	// Free pointer memory

      /* Create a menu item to be return to the caller */
      mi = (Menu_item)xv_create(XV_NULL, MENUITEM,
            MENU_STRING,        getfilename(path),
            MENU_RELEASE,
            MENU_RELEASE_IMAGE,
            MENU_NOTIFY_PROC,   my_action_proc,
	    XV_KEY_DATA,	KEY_ADDR_DATA, addr_notify,
            NULL);

      if (!cnt)
      {
	 /* Create an empty menu to indicate "No files" */
	 /* Note that no NOTIFY_PROC for this item      */
	 Menu_item temp;
         temp = (Menu_item)xv_create(XV_NULL, MENUITEM,
                  MENU_STRING, strdup("<No files>"),
                  MENU_RELEASE,
                  MENU_RELEASE_IMAGE,
	    	  XV_KEY_DATA,	KEY_ADDR_DATA, addr_notify,
                  NULL);
	 xv_set(next_menu, MENU_APPEND_ITEM, temp, NULL);
      }


      /* Truncate the path name for TITLE */
      if ((len = strlen(path)) > 25)
      {
	 (void)strcpy(title,"..."); 
         (void)strcat(title, path + len - 25);
      }
      else
         (void)strcpy(title, path);

      xv_set(next_menu,
               MENU_TITLE_ITEM, title,
               MENU_CLIENT_DATA, strdup(path),
               NULL);
      xv_set(mi, MENU_PULLRIGHT, next_menu, NULL);

      recursion--;
      return mi;
   }

   /* Return a non directory file */
   /* Translate any \ in file name to / */
   fname = getfilename(path); /* Do not free--belongs to menu */
   while (pc=strchr(fname, '\\') ){
       *pc = '/';
   }
   mi = (Menu_item)xv_create(NULL, MENUITEM,
			     MENU_STRING, fname,
			     MENU_RELEASE,
			     MENU_RELEASE_IMAGE,
			     MENU_NOTIFY_PROC, my_action_proc,
			     XV_KEY_DATA, KEY_ADDR_DATA, addr_notify,
			     NULL);
   return mi;
}
コード例 #2
0
ファイル: diffarch.c プロジェクト: KennethWilke/zrt
void
diff_archive (void)
{
  register char *data;
  int check, namelen;
  int err;
  off_t offset;
  struct stat filestat;

#ifndef __MSDOS__
  dev_t dev;
  ino_t ino;
#endif

  errno = EPIPE;		/* FIXME, remove perrors */

  saverec (&head);		/* make sure it sticks around */
  userec (head);		/* and go past it in the archive */
  decode_header (head, &hstat, &head_standard, 1);	/* snarf fields */

  /* Print the record from `head' and `hstat'.  */

  if (flag_verbose)
    {
      if (now_verifying)
	fprintf (stdlis, _("Verify "));
      print_header ();
    }

  switch (head->header.linkflag)
    {

    default:
      WARN ((0, 0, _("Unknown file type '%c' for %s, diffed as normal file"),
		 head->header.linkflag, current_file_name));
      /* Fall through.  */

    case LF_OLDNORMAL:
    case LF_NORMAL:
    case LF_SPARSE:
    case LF_CONTIG:

      /* Appears to be a file.  See if it's really a directory.  */

      namelen = strlen (current_file_name) - 1;
      if (current_file_name[namelen] == '/')
	goto really_dir;

      if (do_stat (&filestat))
	{
	  if (head->header.isextended)
	    skip_extended_headers ();
	  skip_file ((long) hstat.st_size);
	  different++;
	  goto quit;
	}

      if (!S_ISREG (filestat.st_mode))
	{
	  fprintf (stdlis, _("%s: Not a regular file\n"), current_file_name);
	  skip_file ((long) hstat.st_size);
	  different++;
	  goto quit;
	}

      filestat.st_mode &= 07777;
      if (filestat.st_mode != hstat.st_mode)
	sigh (_("Mode"));
      if (filestat.st_uid != hstat.st_uid)
	sigh (_("Uid"));
      if (filestat.st_gid != hstat.st_gid)
	sigh (_("Gid"));
      if (filestat.st_mtime != hstat.st_mtime)
	sigh (_("Mod time"));
      if (head->header.linkflag != LF_SPARSE &&
	  filestat.st_size != hstat.st_size)
	{
	  sigh (_("Size"));
	  skip_file ((long) hstat.st_size);
	  goto quit;
	}

      diff_fd = open (current_file_name, O_NDELAY | O_RDONLY | O_BINARY);

      if (diff_fd < 0 && !flag_absolute_names)
	{
	  char *tmpbuf = tar_xmalloc (strlen (current_file_name) + 2);

	  *tmpbuf = '/';
	  strcpy (tmpbuf + 1, current_file_name);
	  diff_fd = open (tmpbuf, O_NDELAY | O_RDONLY);
	  free (tmpbuf);
	}
      if (diff_fd < 0)
	{
	  ERROR ((0, errno, _("Cannot open %s"), current_file_name));
	  if (head->header.isextended)
	    skip_extended_headers ();
	  skip_file ((long) hstat.st_size);
	  different++;
	  goto quit;
	}

      /* Need to treat sparse files completely differently here.  */

      if (head->header.linkflag == LF_SPARSE)
	diff_sparse_files (hstat.st_size);
      else
	{
	  if (flag_multivol)
	    {
	      assign_string (&save_name, current_file_name);
	      save_totsize = hstat.st_size;
	      /* save_size is set in wantbytes ().  */
	    }
	  wantbytes ((long) (hstat.st_size), compare_chunk);
	  if (flag_multivol)
	    assign_string (&save_name, NULL);
	}

      check = close (diff_fd);
      if (check < 0)
	ERROR ((0, errno, _("Error while closing %s"), current_file_name));

    quit:
      break;

#ifndef __MSDOS__
    case LF_LINK:
      if (do_stat (&filestat))
	break;
      dev = filestat.st_dev;
      ino = filestat.st_ino;
      err = stat (current_link_name, &filestat);
      if (err < 0)
	{
	  if (errno == ENOENT)
	    fprintf (stdlis, _("%s: Does not exist\n"), current_file_name);
	  else
	    WARN ((0, errno, _("Cannot stat file %s"), current_file_name));
	  different++;
	  break;
	}
      if (filestat.st_dev != dev || filestat.st_ino != ino)
	{
	  fprintf (stdlis, _("%s: Not linked to %s\n"),
		   current_file_name, current_link_name);
	  break;
	}
      break;
#endif

#ifdef S_ISLNK
    case LF_SYMLINK:
      {
	char linkbuf[NAMSIZ + 3]; /* FIXME: may be too short.  */

	check = readlink (current_file_name, linkbuf, (sizeof linkbuf) - 1);

	if (check < 0)
	  {
	    if (errno == ENOENT)
	      fprintf (stdlis, _("%s: No such file or directory\n"),
		       current_file_name);
	    else
	      WARN ((0, errno, _("Cannot read link %s"), current_file_name));
	    different++;
	    break;
	  }

	linkbuf[check] = '\0';	/* null-terminate it */
	if (strncmp (current_link_name, linkbuf, (size_t) check) != 0)
	  {
	    fprintf (stdlis, _("%s: Symlink differs\n"), current_link_name);
	    different++;
	  }
      }
      break;
#endif

#ifdef S_IFCHR
    case LF_CHR:
      hstat.st_mode |= S_IFCHR;
      goto check_node;
#endif

#ifdef S_IFBLK
      /* If local system doesn't support block devices, use default case.  */

    case LF_BLK:
      hstat.st_mode |= S_IFBLK;
      goto check_node;
#endif

#ifdef S_ISFIFO
      /* If local system doesn't support FIFOs, use default case.  */

    case LF_FIFO:
#ifdef S_IFIFO
      hstat.st_mode |= S_IFIFO;
#endif
      hstat.st_rdev = 0;	/* FIXME, do we need this? */
      goto check_node;
#endif

    check_node:
      /* FIXME, deal with umask.  */

      if (do_stat (&filestat))
	break;
      if (hstat.st_rdev != filestat.st_rdev)
	{
	  fprintf (stdlis, _("%s: Device numbers changed\n"),
		   current_file_name);
	  different++;
	  break;
	}
      if (
#ifdef S_IFMT
	  hstat.st_mode != filestat.st_mode
#else
	  /* POSIX lossage */
	  (hstat.st_mode & 07777) != (filestat.st_mode & 07777)
#endif
	  )
	{
	  fprintf (stdlis, _("%s: Mode or device-type changed\n"),
		   current_file_name);
	  different++;
	  break;
	}
      break;

    case LF_DUMPDIR:
      data = diff_dir = get_dir_contents (current_file_name, 0);
      if (flag_multivol)
	{
	  assign_string (&save_name, current_file_name);
	  save_totsize = hstat.st_size;
	  /* save_size is set in wantbytes ().  */
	}
      if (data)
	{
	  wantbytes ((long) (hstat.st_size), compare_dir);
	  free (data);
	}
      else
	wantbytes ((long) (hstat.st_size), no_op);
      if (flag_multivol)
	assign_string (&save_name, NULL);
      /* Fall through.  */

    case LF_DIR:
      /* Check for trailing /.  */

      namelen = strlen (current_file_name) - 1;

    really_dir:
      while (namelen && current_file_name[namelen] == '/')
	current_file_name[namelen--] = '\0';	/* zap / */

      if (do_stat (&filestat))
	break;
      if (!S_ISDIR (filestat.st_mode))
	{
	  fprintf (stdlis, _("%s: No longer a directory\n"),
		   current_file_name);
	  different++;
	  break;
	}
      if ((filestat.st_mode & 07777) != (hstat.st_mode & 07777))
	sigh (_("Mode"));
      break;

    case LF_VOLHDR:
      break;

    case LF_MULTIVOL:
      namelen = strlen (current_file_name) - 1;
      if (current_file_name[namelen] == '/')
	goto really_dir;

      if (do_stat (&filestat))
	break;

      if (!S_ISREG (filestat.st_mode))
	{
	  fprintf (stdlis, _("%s: Not a regular file\n"), current_file_name);
	  skip_file ((long) hstat.st_size);
	  different++;
	  break;
	}

      filestat.st_mode &= 07777;
      offset = from_oct (1 + 12, head->header.offset);
      if (filestat.st_size != hstat.st_size + offset)
	{
	  sigh (_("Size"));
	  skip_file ((long) hstat.st_size);
	  different++;
	  break;
	}

      diff_fd = open (current_file_name, O_NDELAY | O_RDONLY | O_BINARY);

      if (diff_fd < 0)
	{
	  WARN ((0, errno, _("Cannot open file %s"), current_file_name));
	  skip_file ((long) hstat.st_size);
	  different++;
	  break;
	}
      err = lseek (diff_fd, offset, 0);
      if (err != offset)
	{
	  WARN ((0, errno, _("Cannot seek to %ld in file %s"),
		     offset, current_file_name));
	  different++;
	  break;
	}

      if (flag_multivol)
	{
	  assign_string (&save_name, current_file_name);
	  save_totsize = filestat.st_size;
	  /* save_size is set in wantbytes ().  */
	}
      wantbytes ((long) (hstat.st_size), compare_chunk);
      if (flag_multivol)
	assign_string (&save_name, NULL);

      check = close (diff_fd);
      if (check < 0)
	ERROR ((0, errno, _("Error while closing %s"), current_file_name));
      break;

    }

  /* We don't need to save it any longer. */

  saverec ((union record **) 0);	/* unsave it */
}