예제 #1
0
void HelloWindow::MessageReceived(BMessage *message)
{ 
	char filename[512];
	//printf("recieved:%d\n",message);
	switch ( message->what )
	{			
		case	B_SIMPLE_DATA	:	{
									entry_ref ref;
									if( message->FindRef("refs", &ref) == B_OK )
										{
										strcpy (filename,"DynaMate - ");
										strcpy ((char *)filename+11,ref.name);
										SetTitle(filename);

										level[256]=255;
										load256(&ref,257,level);
										KillGame();
										KillTitle();
										LaunchGame();
										gameView->totalmoves=0; // added 981018
										}
									}
									break;
		case	LEVELCOMPLETE	:	{
									KillGame();
									uint16 temp=level[256]; //gamla rekordet
									if (totalmoves<level[256]){
										level[256]=totalmoves;
										saverec(level);
										level[256]=temp;
										}
									LaunchTitle();	
									}
									break;

   		case	LEVELABANDONED	:	{
									KillGame();
									LaunchTitle();
									}
									break;
 								
		default	:	BWindow::MessageReceived(message);
								break;
	}
}
예제 #2
0
/*
 * Extract a file from the archive.
 */
void
extract_archive ()
{
  register char *data;
  int fd, check, namelen, written, openflag;
  long size;
  struct utimbuf acc_upd_times;
  register int skipcrud;
  register int i;
  /*	int sparse_ind = 0;*/
  union record *exhdr;
  struct saved_dir_info *tmp;
  /*	int end_nulls; */

  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 */

  if ((f_confirm && !confirm ("extract", current_file_name)) ||
      (f_exstdout && head->header.linkflag != LF_OLDNORMAL &&
       head->header.linkflag != LF_NORMAL &&
       head->header.linkflag != LF_CONTIG))
    {
      if (head->header.isextended)
	skip_extended_headers ();
      skip_file ((long) hstat.st_size);
      saverec ((union record **) 0);
      return;
    }

  /* Print the record from 'head' and 'hstat' */
  if (f_verbose)
    print_header ();

  /*
	 * Check for fully specified pathnames and other atrocities.
	 *
	 * Note, we can't just make a pointer to the new file name,
	 * since saverec() might move the header and adjust "head".
	 * We have to start from "head" every time we want to touch
	 * the header record.
	 */
  skipcrud = 0;
  while (!f_absolute_paths
	 && '/' == current_file_name[skipcrud])
    {
      static int warned_once = 0;

      skipcrud++;		/* Force relative path */
      if (!warned_once++)
	{
	  msg ("Removing leading / from absolute path names in the archive.");
	}
    }

  switch (head->header.linkflag)
    {

    default:
      msg ("Unknown file type '%c' for %s, extracted as normal file",
	   head->header.linkflag, skipcrud + current_file_name);
      /* FALL THRU */

      /*
	  * JK - What we want to do if the file is sparse is loop through
	  * the array of sparse structures in the header and read in
	  * and translate the character strings representing  1) the offset
	  * at which to write and 2) how many bytes to write into numbers,
	  * which we store into the scratch array, "sparsearray".  This
	  * array makes our life easier the same way it did in creating
	  * the tar file that had to deal with a sparse file.
	  *
	  * After we read in the first five (at most) sparse structures,
	  * we check to see if the file has an extended header, i.e.,
	  * if more sparse structures are needed to describe the contents
	  * of the new file.  If so, we read in the extended headers
	  * and continue to store their contents into the sparsearray.
	  */
    case LF_SPARSE:
      sp_array_size = 10;
      sparsearray = (struct sp_array *) ck_malloc (sp_array_size * sizeof (struct sp_array));
      for (i = 0; i < SPARSE_IN_HDR; i++)
	{
	  sparsearray[i].offset =
	    from_oct (1 + 12, head->header.sp[i].offset);
	  sparsearray[i].numbytes =
	    from_oct (1 + 12, head->header.sp[i].numbytes);
	  if (!sparsearray[i].numbytes)
	    break;
	}

      /*		end_nulls = from_oct(1+12, head->header.ending_blanks);*/

      if (head->header.isextended)
	{
	  /* read in the list of extended headers
			    and translate them into the sparsearray
			    as before */

	  /* static */ int ind = SPARSE_IN_HDR;

	  for (;;)
	    {

	      exhdr = findrec ();
	      for (i = 0; i < SPARSE_EXT_HDR; i++)
		{

		  if (i + ind > sp_array_size - 1)
		    {
		      /*
					  * realloc the scratch area
					  * since we've run out of room --
					  */
		      sparsearray = (struct sp_array *)
			ck_realloc (sparsearray,
			    2 * sp_array_size * (sizeof (struct sp_array)));
		      sp_array_size *= 2;
		    }
		  if (!exhdr->ext_hdr.sp[i].numbytes)
		    break;
		  sparsearray[i + ind].offset =
		    from_oct (1 + 12, exhdr->ext_hdr.sp[i].offset);
		  sparsearray[i + ind].numbytes =
		    from_oct (1 + 12, exhdr->ext_hdr.sp[i].numbytes);
		}
	      if (!exhdr->ext_hdr.isextended)
		break;
	      else
		{
		  ind += SPARSE_EXT_HDR;
		  userec (exhdr);
		}
	    }
	  userec (exhdr);
	}

      /* FALL THRU */
    case LF_OLDNORMAL:
    case LF_NORMAL:
    case LF_CONTIG:
      /*
		  * Appears to be a file.
		  * See if it's really a directory.
		  */
      namelen = strlen (skipcrud + current_file_name) - 1;
      if (current_file_name[skipcrud + namelen] == '/')
	goto really_dir;

      /* FIXME, deal with protection issues */
    again_file:
      openflag = (f_keep ?
		  O_BINARY | O_NDELAY | O_WRONLY | O_CREAT | O_EXCL :
		  O_BINARY | O_NDELAY | O_WRONLY | O_CREAT | O_TRUNC)
	| ((head->header.linkflag == LF_SPARSE) ? 0 : O_APPEND);
      /*
			  * JK - The last | is a kludge to solve the problem
			  * the O_APPEND flag  causes with files we are
			  * trying to make sparse:  when a file is opened
			  * with O_APPEND, it writes  to the last place
			  * that something was written, thereby ignoring
			  * any lseeks that we have done.  We add this
			  * extra condition to make it able to lseek when
			  * a file is sparse, i.e., we don't open the new
			  * file with this flag.  (Grump -- this bug caused
			  * me to waste a good deal of time, I might add)
			  */

      if (f_exstdout)
	{
	  fd = 1;
	  goto extract_file;
	}

      if (f_unlink && !f_keep) {
	if (unlink(skipcrud + current_file_name) == -1)
		if (errno != ENOENT)
		   msg_perror ("Could not unlink %s",
                      skipcrud + current_file_name);
      }

#ifdef O_CTG
      /*
		  * Contiguous files (on the Masscomp) have to specify
		  * the size in the open call that creates them.
		  */
      if (head->header.linkflag == LF_CONTIG)
	fd = open ((longname ? longname : head->header.name)
		   + skipcrud,
		   openflag | O_CTG,
		   hstat.st_mode, hstat.st_size);
      else
#endif
	{
#ifdef NO_OPEN3
	  /*
			  * On raw V7 we won't let them specify -k (f_keep), but
			  * we just bull ahead and create the files.
			  */
	  fd = creat ((longname
		       ? longname
		       : head->header.name) + skipcrud,
		      hstat.st_mode);
#else
	  /*
			  * With 3-arg open(), we can do this up right.
			  */
	  fd = open (skipcrud + current_file_name,
		     openflag, hstat.st_mode);
#endif
	}

      if (fd < 0)
	{
	  if (make_dirs (skipcrud + current_file_name))
	    goto again_file;
	  msg_perror ("Could not create file %s",
		      skipcrud + current_file_name);
	  if (head->header.isextended)
	    skip_extended_headers ();
	  skip_file ((long) hstat.st_size);
	  goto quit;
	}

    extract_file:
      if (head->header.linkflag == LF_SPARSE)
	{
	  char *name;
	  int namelen;

	  /*
			  * Kludge alert.  NAME is assigned to header.name
			  * because during the extraction, the space that
			  * contains the header will get scribbled on, and
			  * the name will get munged, so any error messages
			  * that happen to contain the filename will look
			  * REAL interesting unless we do this.
			  */
	  namelen = strlen (skipcrud + current_file_name) + 1;
	  name = (char *) ck_malloc ((sizeof (char)) * namelen);
	  bcopy (skipcrud + current_file_name, name, namelen);
	  size = hstat.st_size;
	  extract_sparse_file (fd, &size, hstat.st_size, name);
	}
      else
	for (size = hstat.st_size;
	     size > 0;
	     size -= written)
	  {

	    /*			long	offset,
				 numbytes;*/

	    if (f_multivol)
	      {
		save_name = current_file_name;
		save_totsize = hstat.st_size;
		save_sizeleft = size;
	      }

	    /*
			  * Locate data, determine max length
			  * writeable, write it, record that
			  * we have used the data, then check
			  * if the write worked.
			  */
	    data = findrec ()->charptr;
	    if (data == NULL)
	      {			/* Check it... */
		msg ("Unexpected EOF on archive file");
		break;
	      }
	    /*
			  * JK - If the file is sparse, use the sparsearray
			  * that we created before to lseek into the new
			  * file the proper amount, and to see how many
			  * bytes we want to write at that position.
			  */
	    /*			if (head->header.linkflag == LF_SPARSE) {
				 off_t pos;

				 pos = lseek(fd, (off_t) sparsearray[sparse_ind].offset, 0);
				 printf("%d at %d\n", (int) pos, sparse_ind);
				 written = sparsearray[sparse_ind++].numbytes;
			 } else*/
	    written = endofrecs ()->charptr - data;
	    if (written > size)
	      written = size;
	    errno = 0;
	    check = write (fd, data, written);
	    /*
			  * The following is in violation of strict
			  * typing, since the arg to userec
			  * should be a struct rec *.  FIXME.
			  */
	    userec ((union record *) (data + written - 1));
	    if (check == written)
	      continue;
	    /*
			  * Error in writing to file.
			  * Print it, skip to next file in archive.
			  */
	    if (check < 0)
	      msg_perror ("couldn't write to file %s",
			  skipcrud + current_file_name);
	    else
	      msg ("could only write %d of %d bytes to file %s",
		   check, written, skipcrud + current_file_name);
	    skip_file ((long) (size - written));
	    break;		/* Still do the close, mod time, chmod, etc */
	  }

      if (f_multivol)
	save_name = 0;

      /* If writing to stdout, don't try to do anything
			    to the filename; it doesn't exist, or we don't
			    want to touch it anyway */
      if (f_exstdout)
	break;

      /*		if (head->header.isextended) {
			 register union record *exhdr;
			 register int i;

			 for (i = 0; i < 21; i++) {
				 long offset;

				 if (!exhdr->ext_hdr.sp[i].numbytes)
					 break;
				 offset = from_oct(1+12,
						 exhdr->ext_hdr.sp[i].offset);
				 written = from_oct(1+12,
						 exhdr->ext_hdr.sp[i].numbytes);
				 lseek(fd, offset, 0);
				 check = write(fd, data, written);
				 if (check == written) continue;

			 }


		 }*/
      check = close (fd);
      if (check < 0)
	{
	  msg_perror ("Error while closing %s",
		      skipcrud + current_file_name);
	}


    set_filestat:

      /*
		  * If we are root, set the owner and group of the extracted
		  * file.  This does what is wanted both on real Unix and on
		  * System V.  If we are running as a user, we extract as that
		  * user; if running as root, we extract as the original owner.
		  */
      if (we_are_root || f_do_chown)
	{
	  if (chown (skipcrud + current_file_name,
		     hstat.st_uid, hstat.st_gid) < 0)
	    {
	      msg_perror ("cannot chown file %s to uid %d gid %d",
			  skipcrud + current_file_name,
			  hstat.st_uid, hstat.st_gid);
	    }
	}

      /*
       * Set the modified time of the file.
       *
       * Note that we set the accessed time to "now", which
       * is really "the time we started extracting files".
       * unless f_gnudump is used, in which case .st_atime is used
       */
      if (!f_modified)
	{
	  /* fixme if f_gnudump should set ctime too, but how? */
	  if (f_gnudump)
	    acc_upd_times.actime = hstat.st_atime;
	  else
	    acc_upd_times.actime = now;	/* Accessed now */
	  acc_upd_times.modtime = hstat.st_mtime;	/* Mod'd */
	  if (utime (skipcrud + current_file_name,
		     &acc_upd_times) < 0)
	    {
	      msg_perror ("couldn't change access and modification times of %s", skipcrud + current_file_name);
	    }
	}
      /* We do the utime before the chmod because some versions of
		   utime are broken and trash the modes of the file.  Since
		   we then change the mode anyway, we don't care. . . */

      /*
		 * If '-k' is not set, open() or creat() could have saved
		 * the permission bits from a previously created file,
		 * ignoring the ones we specified.
		 * Even if -k is set, if the file has abnormal
		 * mode bits, we must chmod since writing or chown() has
		 * probably reset them.
		 *
		 * If -k is set, we know *we* created this file, so the mode
		 * bits were set by our open().   If the file is "normal", we
		 * skip the chmod.  This works because we did umask(0) if -p
		 * is set, so umask will have left the specified mode alone.
		 */
      if ((!f_keep)
	  || (hstat.st_mode & (S_ISUID | S_ISGID | S_ISVTX)))
	{
	  if (chmod (skipcrud + current_file_name,
		     notumask & (int) hstat.st_mode) < 0)
	    {
	      msg_perror ("cannot change mode of file %s to 0%o",
			  skipcrud + current_file_name,
			  notumask & (int) hstat.st_mode);
	    }
	}

    quit:
      break;

    case LF_LINK:
    again_link:
      {
	struct stat st1, st2;

        if (f_unlink && !f_keep) {
	  if (unlink(skipcrud + current_file_name) == -1)
		if (errno != ENOENT)
		   msg_perror ("Could not unlink %s",
                      skipcrud + current_file_name);
        }

	check = link (current_link_name, skipcrud + current_file_name);

	if (check == 0)
	  break;
	if (make_dirs (skipcrud + current_file_name))
	  goto again_link;
	if (f_gnudump && errno == EEXIST)
	  break;
	if (stat (current_link_name, &st1) == 0
	    && stat (current_file_name + skipcrud, &st2) == 0
	    && st1.st_dev == st2.st_dev
	    && st1.st_ino == st2.st_ino)
	  break;
	msg_perror ("Could not link %s to %s",
		    skipcrud + current_file_name,
		    current_link_name);
      }
      break;

#ifdef S_ISLNK
    case LF_SYMLINK:
    again_symlink:
      if (f_unlink && !f_keep) {
	  if (unlink(skipcrud + current_file_name) == -1)
		if (errno != ENOENT)
		   msg_perror ("Could not unlink %s",
                      skipcrud + current_file_name);
      }

      check = symlink (current_link_name,
		       skipcrud + current_file_name);
      /* FIXME, don't worry uid, gid, etc... */
      if (check == 0)
	break;
      if (make_dirs (current_file_name + skipcrud))
	goto again_symlink;
      msg_perror ("Could not create symlink to %s",
		  current_link_name);
      break;
#endif

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

#ifdef S_IFBLK
    case LF_BLK:
      hstat.st_mode |= S_IFBLK;
#endif
#if defined(S_IFCHR) || defined(S_IFBLK)
    make_node:
      if (f_unlink && !f_keep) {
	  if (unlink(skipcrud + current_file_name) == -1)
		if (errno != ENOENT)
		   msg_perror ("Could not unlink %s",
                      skipcrud + current_file_name);
      }

      check = mknod (current_file_name + skipcrud,
		     (int) hstat.st_mode, (int) hstat.st_rdev);
      if (check != 0)
	{
	  if (make_dirs (skipcrud + current_file_name))
	    goto make_node;
	  msg_perror ("Could not make %s",
		      current_file_name + skipcrud);
	  break;
	};
      goto set_filestat;
#endif

#ifdef S_ISFIFO
      /* If local system doesn't support FIFOs, use default case */
    case LF_FIFO:
    make_fifo:
      if (f_unlink && !f_keep) {
	  if (unlink(skipcrud + current_file_name) == -1)
		if (errno != ENOENT)
		   msg_perror ("Could not unlink %s",
                      skipcrud + current_file_name);
      }

      check = mkfifo (current_file_name + skipcrud,
		      (int) hstat.st_mode);
      if (check != 0)
	{
	  if (make_dirs (current_file_name + skipcrud))
	    goto make_fifo;
	  msg_perror ("Could not make %s",
		      skipcrud + current_file_name);
	  break;
	};
      goto set_filestat;
#endif

    case LF_DIR:
    case LF_DUMPDIR:
      namelen = strlen (current_file_name + skipcrud) - 1;
    really_dir:
      /* Check for trailing /, and zap as many as we find. */
      while (namelen
	     && current_file_name[skipcrud + namelen] == '/')
	current_file_name[skipcrud + namelen--] = '\0';
      if (f_gnudump)
	{			/* Read the entry and delete files
					   that aren't listed in the archive */
	  gnu_restore (skipcrud);

	}
      else if (head->header.linkflag == LF_DUMPDIR)
	skip_file ((long) (hstat.st_size));


    again_dir:
      check = mkdir (skipcrud + current_file_name,
		     (we_are_root ? 0 : 0300) | (int) hstat.st_mode);
      if (check != 0)
	{
	  struct stat st1;

	  if (make_dirs (skipcrud + current_file_name))
	    goto again_dir;
	  /* If we're trying to create '.', let it be. */
	  if (current_file_name[skipcrud + namelen] == '.' &&
	      (namelen == 0 ||
	       current_file_name[skipcrud + namelen - 1] == '/'))
	    goto check_perms;
	  if (errno == EEXIST
	      && stat (skipcrud + current_file_name, &st1) == 0
	      && (S_ISDIR (st1.st_mode)))
	    break;
	  msg_perror ("Could not create directory %s", skipcrud + current_file_name);
	  break;
	}

    check_perms:
      if (!we_are_root && 0300 != (0300 & (int) hstat.st_mode))
	{
	  hstat.st_mode |= 0300;
	  msg ("Added write and execute permission to directory %s",
	       skipcrud + current_file_name);
	}

      /*
       * If we are root, set the owner and group of the extracted
       * file.  This does what is wanted both on real Unix and on
       * System V.  If we are running as a user, we extract as that
       * user; if running as root, we extract as the original owner.
       */
      if (we_are_root || f_do_chown)
	{
	  if (chown (skipcrud + current_file_name,
		     hstat.st_uid, hstat.st_gid) < 0)
	    {
	      msg_perror ("cannot chown file %s to uid %d gid %d",
			  skipcrud + current_file_name,
			  hstat.st_uid, hstat.st_gid);
	    }
	}

      if (!f_modified)
	{
	  tmp = ((struct saved_dir_info *)
		 ck_malloc (sizeof (struct saved_dir_info)));
	  tmp->path = (char *) ck_malloc (strlen (skipcrud
						  + current_file_name) + 1);
	  strcpy (tmp->path, skipcrud + current_file_name);
	  tmp->mode = hstat.st_mode;
	  tmp->atime = hstat.st_atime;
	  tmp->mtime = hstat.st_mtime;
	  tmp->next = saved_dir_info_head;
	  saved_dir_info_head = tmp;
	}
      else
	{
	  /* This functions exactly as the code for set_filestat above. */
	  if ((!f_keep)
	      || (hstat.st_mode & (S_ISUID | S_ISGID | S_ISVTX)))
	    {
	      if (chmod (skipcrud + current_file_name,
			 notumask & (int) hstat.st_mode) < 0)
		{
		  msg_perror ("cannot change mode of file %s to 0%o",
			      skipcrud + current_file_name,
			      notumask & (int) hstat.st_mode);
		}
	    }
	}
      break;

    case LF_VOLHDR:
      if (f_verbose)
	{
	  printf ("Reading %s\n", current_file_name);
	}
      break;

    case LF_NAMES:
      extract_mangle (head);
      break;

    case LF_MULTIVOL:
      msg ("Can't extract '%s'--file is continued from another volume\n", current_file_name);
      skip_file ((long) hstat.st_size);
      break;

    case LF_LONGNAME:
    case LF_LONGLINK:
      msg ("Visible long name error\n");
      skip_file ((long) hstat.st_size);
      break;
    }

  /* We don't need to save it any longer. */
  saverec ((union record **) 0);/* Unsave it */
}
예제 #3
0
int main()
{
    int field[25][50];
    int python[1000][2];
    int fd[2];
    int k,i,j,n=1,counter=0, over,t2;
    char directory[] = "Music/x.mid";

    allegro_init();
    install_keyboard();
    set_color_depth(32);
    set_gfx_mode(GFX_AUTODETECT_WINDOWED, 600, 272, 0, 0);
    install_sound(DIGI_AUTODETECT,MIDI_AUTODETECT,NULL);

    BITMAP *buffer = create_bitmap(600,272);
    MIDI *music;
    while(n>0)
    {
        dir = r;
        length = 4;
        score = 0;
        t = 100;
        sp = 1;
        over = 0;
        look = 'r';
        t2 = 1;
        python[0][0] = 15;
        python[0][1] = 10;
        python[1][0] = 15;
        python[1][1] = 9;
        python[2][0] = 15;
        python[2][1] = 8;
        python[3][0] = 15;
        python[3][1] = 7;

        srand(time(NULL));
        directory[6] = intchar(rand()%9 + 1);

        music = load_midi(directory);
        play_midi(music,0);

        clear_to_color(screen,0x000000);
        opening();
        menu_mode(field);
        init(field);

        position(field,python);  // position the snake
        food(field,fd);
        guardi = python[length-1][0];
        guardj = python[length-1][1];
        display(field,python,fd,t2);

        while(over!=1)
        {
            if(t2<10) {
                t2++;
            }
            guardi = python[length-1][0];
            guardj = python[length-1][1];
            save = dir;
            python[length][0] = i;
            python[length][1] = j;
            rest(10);
            if(keypressed()) {
                dir = readkey();
            }
            else if ((dir & 0xff) == 'w') dir =u;
            else if ((dir & 0xff) == 's') dir =d;
            else if ((dir & 0xff) == 'a') dir =l;
            else if ((dir & 0xff) == 'd') dir =r;

            if((dir==u)||(dir==d)||(dir==l)||(dir==r)) {
                over = analysis(field,python,fd);
                rest(t-10);
            }
            else if(dir==esc) {
                over=1;
                n=0;
            }
            else {
                dir = save;
                over = analysis(field,python,fd);
                rest(t-10);
            };
            display(field,python,fd,t2);



        }
        portal1[0] = 50;
        portal1[1] = 50;
        portal2[0] = 50;
        portal2[1] = 50;
        clear_to_color(screen,0xFFFFFF);
        textout_ex(screen,font,"Score: ",225,160,0x02094A,0xF7FF0B);
        outnumber(265,160,score);
        saverec(field,python,fd);
        destroy_midi(music);
        rest(100);
        if(readkey()==esc) {
            n=0;
        }

    }

    destroy_bitmap(buffer);
    return 0;
}
예제 #4
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 */
}