Exemplo n.º 1
0
Lisp_Object
encode_current_directory (void)
{
  Lisp_Object dir;

  dir = BVAR (current_buffer, directory);

  dir = Funhandled_file_name_directory (dir);

  /* If the file name handler says that dir is unreachable, use
     a sensible default. */
  if (NILP (dir))
    dir = build_string ("~");

  dir = expand_and_dir_to_file (dir, Qnil);

  if (NILP (Ffile_accessible_directory_p (dir)))
    report_file_error ("Setting current directory",
		       BVAR (current_buffer, directory));

  /* Remove "/:" from DIR and encode it.  */
  dir = ENCODE_FILE (remove_slash_colon (dir));

  if (! file_accessible_directory_p (dir))
    report_file_error ("Setting current directory",
		       BVAR (current_buffer, directory));

  return dir;
}
Exemplo n.º 2
0
static int
open_audio_port (AudioContext return_ac, AudioContext desc)
{
  ALconfig config = ALnewconfig();
  long params[2];

  adjust_audio_volume (& desc->device);
  return_ac->ac_left_speaker_gain = desc->ac_left_speaker_gain;
  return_ac->ac_right_speaker_gain = desc->ac_right_speaker_gain;
  params[0] = AL_OUTPUT_RATE;
  params[1] = desc->ac_output_rate;
  ALsetparams (desc->ac_device, params, 2);
  return_ac->ac_output_rate = desc->ac_output_rate;
  if (set_channels (config, desc->ac_nchan)==-1)
    return -1;
  return_ac->ac_nchan = desc->ac_nchan;
  if (set_output_format (config, desc->ac_format)==-1)
    return -1;
  return_ac->ac_format = desc->ac_format;
  ALsetqueuesize (config, (long) CHUNKSIZE);
  return_ac->ac_port = ALopenport("XEmacs audio output", "w", config);
  ALfreeconfig (config);
  if (return_ac->ac_port==0)
    {
      report_file_error ("Opening audio output port", Qnil);
      return -1;
    }
  return 0;
}
Exemplo n.º 3
0
static void
report_error (char *file, int fd)
{
  if (fd)
    close (fd);
  report_file_error ("Cannot unexec", Fcons (build_string (file), Qnil));
}
Exemplo n.º 4
0
static struct dirent *
read_dirent (DIR *dir, Lisp_Object dirname)
{
  while (true)
    {
      errno = 0;
      struct dirent *dp = readdir (dir);
      if (dp || errno == 0)
	return dp;
      if (! (errno == EAGAIN || errno == EINTR))
	{
#ifdef WINDOWSNT
	  /* The MS-Windows implementation of 'opendir' doesn't
	     actually open a directory until the first call to
	     'readdir'.  If 'readdir' fails to open the directory, it
	     sets errno to ENOENT or EACCES, see w32.c.  */
	  if (errno == ENOENT || errno == EACCES)
	    report_file_error ("Opening directory", dirname);
#endif
	  report_file_error ("Reading directory", dirname);
	}
      QUIT;
    }
}
Exemplo n.º 5
0
static int
set_channels (ALconfig config, unsigned int nchan)
{
  switch (nchan)
    {
    case 1: ALsetchannels (config, AL_MONO); break;
#if HAVE_STEREO
    case 2: ALsetchannels (config, AL_STEREO); break;
#endif /* HAVE_STEREO */
    default:
      report_file_error ("Unsupported channel count",
			 Fcons (make_int (nchan), Qnil));
      return -1;
    }
  return 0;
}
Exemplo n.º 6
0
static AudioContext
audio_initialize (unsigned char *data, int length, int volume)
{
  Lisp_Object audio_port_state[3];
  static AudioContextRec desc;
  AudioContext ac;

  desc.ac_right_speaker_gain
    = desc.ac_left_speaker_gain
      = volume * 256 / 100;
  desc.ac_device = AL_DEFAULT_DEVICE;

#if HAVE_SND_FILES
  if (LOOKING_AT_SND_HEADER_P (data))
    {
      if (parse_snd_header (data, length, & desc)==-1)
	report_file_error ("decoding .snd header", Qnil);
    }
  else
#endif
      {
	desc.ac_data = data;
	desc.ac_size = length;
	desc.ac_output_rate = DEFAULT_SAMPLING_RATE;
	desc.ac_nchan = DEFAULT_CHANNEL_COUNT;
	desc.ac_format = DEFAULT_FORMAT;
	desc.ac_write_chunk_function = write_mulaw_8_chunk;
      }

  /* Make sure that the audio port is reset to
     its initial characteristics after exit */
  ALgetparams (desc.ac_device, saved_device_state,
	       sizeof (saved_device_state) / sizeof (long));
  audio_port_state[0] = make_int (saved_device_state[1]);
  audio_port_state[1] = make_int (saved_device_state[3]);
  audio_port_state[2] = make_int (saved_device_state[5]);
  record_unwind_protect (restore_audio_port,
			 Fvector (3, &audio_port_state[0]));

  ac = initialize_audio_port (& desc);
  desc = * ac;
  return ac;
}
Exemplo n.º 7
0
static int
set_output_format (ALconfig config, AudioFormat format)
{
  long samplesize;
  long old_samplesize;

  switch (format)
    {
#if HAVE_MULAW_8
    case AFmulaw8:
#endif
#if HAVE_LINEAR
    case AFlinear16:
#endif
#if HAVE_MULAW_8 || HAVE_LINEAR
      samplesize = AL_SAMPLE_16;
      break;
#endif
#if HAVE_LINEAR
    case AFlinear8:
      samplesize = AL_SAMPLE_8;
      break;
    case AFlinear24:
#if HAVE_LINEAR_32
    case AFlinear32:
      samplesize = AL_SAMPLE_24;
      break;
#endif
#endif
    default:
      report_file_error ("Unsupported audio format",
			 Fcons (make_int (format), Qnil));
      return -1;
    }
  old_samplesize = ALgetwidth (config);
  if (old_samplesize==samplesize)
    return 0;
  ALsetwidth (config, samplesize);
  return 1;
}
Exemplo n.º 8
0
Arquivo: dired.c Projeto: fs814/emacs
Lisp_Object
directory_files_internal (Lisp_Object directory, Lisp_Object full,
			  Lisp_Object match, Lisp_Object nosort, bool attrs,
			  Lisp_Object id_format)
{
  DIR *d;
  int fd;
  ptrdiff_t directory_nbytes;
  Lisp_Object list, dirfilename, encoded_directory;
  struct re_pattern_buffer *bufp = NULL;
  bool needsep = 0;
  ptrdiff_t count = SPECPDL_INDEX ();
  struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5;
  struct dirent *dp;
#ifdef WINDOWSNT
  Lisp_Object w32_save = Qnil;
#endif

  /* Don't let the compiler optimize away all copies of DIRECTORY,
     which would break GC; see Bug#16986.  Although this is required
     only in the common case where GC_MARK_STACK == GC_MAKE_GCPROS_NOOPS,
     it shouldn't break anything in the other cases.  */
  Lisp_Object volatile directory_volatile = directory;

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

  d = open_directory (SSDATA (dirfilename), &fd);
  if (d == NULL)
    report_file_error ("Opening directory", directory);

  /* 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_ptr (directory_files_internal_unwind, d);

#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 (;;)
    {
      ptrdiff_t len;
      bool wanted = 0;
      Lisp_Object name, finalname;
      struct gcpro gcpro1, gcpro2;

      errno = 0;
      dp = readdir (d);
      if (!dp)
	{
	  if (errno == EAGAIN || errno == EINTR)
	    {
	      QUIT;
	      continue;
	    }
	  break;
	}

      len = dirent_namelen (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)
	  || re_search (bufp, SSDATA (name), len, 0, len, 0) >= 0)
	wanted = 1;

      immediate_quit = 0;

      if (wanted)
	{
	  if (!NILP (full))
	    {
	      Lisp_Object fullname;
	      ptrdiff_t nbytes = len + directory_nbytes + needsep;
	      ptrdiff_t 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 = multibyte_chars_in_text (SDATA (fullname), nbytes);

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

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

	      finalname = fullname;
	    }
	  else
	    finalname = name;

	  if (attrs)
	    {
	      Lisp_Object fileattrs
		= file_attributes (fd, dp->d_name, id_format);
	      list = Fcons (Fcons (finalname, fileattrs), list);
	    }
	  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);

  (void) directory_volatile;
  RETURN_UNGCPRO (list);
}
Exemplo n.º 9
0
Lisp_Object
get_doc_string (Lisp_Object filepos, bool unibyte, bool definition)
{
  char *from, *to, *name, *p, *p1;
  int fd;
  int offset;
  EMACS_INT position;
  Lisp_Object file, tem, pos;
  ptrdiff_t count;
  USE_SAFE_ALLOCA;

  if (INTEGERP (filepos))
    {
      file = Vdoc_file_name;
      pos = filepos;
    }
  else if (CONSP (filepos))
    {
      file = XCAR (filepos);
      pos = XCDR (filepos);
    }
  else
    return Qnil;

  position = eabs (XINT (pos));

  if (!STRINGP (Vdoc_directory))
    return Qnil;

  if (!STRINGP (file))
    return Qnil;

  /* Put the file name in NAME as a C string.
     If it is relative, combine it with Vdoc_directory.  */

  tem = Ffile_name_absolute_p (file);
  file = ENCODE_FILE (file);
  Lisp_Object docdir
    = NILP (tem) ? ENCODE_FILE (Vdoc_directory) : empty_unibyte_string;
  ptrdiff_t docdir_sizemax = SBYTES (docdir) + 1;
#ifndef CANNOT_DUMP
  docdir_sizemax = max (docdir_sizemax, sizeof sibling_etc);
#endif
  name = SAFE_ALLOCA (docdir_sizemax + SBYTES (file));
  lispstpcpy (lispstpcpy (name, docdir), file);

  fd = emacs_open (name, O_RDONLY, 0);
  if (fd < 0)
    {
#ifndef CANNOT_DUMP
      if (!NILP (Vpurify_flag))
	{
	  /* Preparing to dump; DOC file is probably not installed.
	     So check in ../etc.  */
	  lispstpcpy (stpcpy (name, sibling_etc), file);

	  fd = emacs_open (name, O_RDONLY, 0);
	}
#endif
      if (fd < 0)
	{
	  if (errno == EMFILE || errno == ENFILE)
	    report_file_error ("Read error on documentation file", file);

	  SAFE_FREE ();
	  AUTO_STRING (cannot_open, "Cannot open doc string file \"");
	  AUTO_STRING (quote_nl, "\"\n");
	  return concat3 (cannot_open, file, quote_nl);
	}
    }
  count = SPECPDL_INDEX ();
  record_unwind_protect_int (close_file_unwind, fd);

  /* Seek only to beginning of disk block.  */
  /* Make sure we read at least 1024 bytes before `position'
     so we can check the leading text for consistency.  */
  offset = min (position, max (1024, position % (8 * 1024)));
  if (TYPE_MAXIMUM (off_t) < position
      || lseek (fd, position - offset, 0) < 0)
    error ("Position %"pI"d out of range in doc string file \"%s\"",
	   position, name);

  /* Read the doc string into get_doc_string_buffer.
     P points beyond the data just read.  */

  p = get_doc_string_buffer;
  while (1)
    {
      ptrdiff_t space_left = (get_doc_string_buffer_size - 1
			      - (p - get_doc_string_buffer));
      int nread;

      /* Allocate or grow the buffer if we need to.  */
      if (space_left <= 0)
	{
	  ptrdiff_t in_buffer = p - get_doc_string_buffer;
	  get_doc_string_buffer
	    = xpalloc (get_doc_string_buffer, &get_doc_string_buffer_size,
		       16 * 1024, -1, 1);
	  p = get_doc_string_buffer + in_buffer;
	  space_left = (get_doc_string_buffer_size - 1
			- (p - get_doc_string_buffer));
	}

      /* Read a disk block at a time.
         If we read the same block last time, maybe skip this?  */
      if (space_left > 1024 * 8)
	space_left = 1024 * 8;
      nread = emacs_read (fd, p, space_left);
      if (nread < 0)
	report_file_error ("Read error on documentation file", file);
      p[nread] = 0;
      if (!nread)
	break;
      if (p == get_doc_string_buffer)
	p1 = strchr (p + offset, '\037');
      else
	p1 = strchr (p, '\037');
      if (p1)
	{
	  *p1 = 0;
	  p = p1;
	  break;
	}
      p += nread;
    }
  unbind_to (count, Qnil);
  SAFE_FREE ();

  /* Sanity checking.  */
  if (CONSP (filepos))
    {
      int test = 1;
      /* A dynamic docstring should be either at the very beginning of a "#@
	 comment" or right after a dynamic docstring delimiter (in case we
	 pack several such docstrings within the same comment).  */
      if (get_doc_string_buffer[offset - test] != '\037')
	{
	  if (get_doc_string_buffer[offset - test++] != ' ')
	    return Qnil;
	  while (get_doc_string_buffer[offset - test] >= '0'
		 && get_doc_string_buffer[offset - test] <= '9')
	    test++;
	  if (get_doc_string_buffer[offset - test++] != '@'
	      || get_doc_string_buffer[offset - test] != '#')
	    return Qnil;
	}
    }
  else
    {
      int test = 1;
      if (get_doc_string_buffer[offset - test++] != '\n')
	return Qnil;
      while (get_doc_string_buffer[offset - test] > ' ')
	test++;
      if (get_doc_string_buffer[offset - test] != '\037')
	return Qnil;
    }

  /* Scan the text and perform quoting with ^A (char code 1).
     ^A^A becomes ^A, ^A0 becomes a null char, and ^A_ becomes a ^_.  */
  from = get_doc_string_buffer + offset;
  to = get_doc_string_buffer + offset;
  while (from != p)
    {
      if (*from == 1)
	{
	  int c;

	  from++;
	  c = *from++;
	  if (c == 1)
	    *to++ = c;
	  else if (c == '0')
	    *to++ = 0;
	  else if (c == '_')
	    *to++ = 037;
	  else
	    {
	      unsigned char uc = c;
	      error ("\
Invalid data in documentation file -- %c followed by code %03o",
		     1, uc);
	    }
	}
      else
	*to++ = *from++;
    }

  /* If DEFINITION, read from this buffer
     the same way we would read bytes from a file.  */
  if (definition)
    {
      read_bytecode_pointer = (unsigned char *) get_doc_string_buffer + offset;
      return Fread (Qlambda);
    }

  if (unibyte)
    return make_unibyte_string (get_doc_string_buffer + offset,
				to - (get_doc_string_buffer + offset));
  else
    {
      /* The data determines whether the string is multibyte.  */
      ptrdiff_t nchars
	= multibyte_chars_in_text (((unsigned char *) get_doc_string_buffer
				    + offset),
				   to - (get_doc_string_buffer + offset));
      return make_string_from_bytes (get_doc_string_buffer + offset,
				     nchars,
				     to - (get_doc_string_buffer + offset));
    }
}
Exemplo n.º 10
0
int CAimProto::receiving_file(file_transfer *ft, HANDLE hServerPacketRecver, NETLIBPACKETRECVER &packetRecv)
{
	debugLogA("P2P: Entered file receiving thread.");
	bool failed = true;
	bool failed_conn = false;
	bool accepted_file = false;
	int fid = -1;

	oft2 *oft = NULL;

	ft->pfts.tszWorkingDir = mir_utf8decodeT(ft->file);

	//start listen for packets stuff
	for (;;) {
		int recvResult = packetRecv.bytesAvailable - packetRecv.bytesUsed;
		if (recvResult <= 0)
			recvResult = CallService(MS_NETLIB_GETMOREPACKETS, (WPARAM)hServerPacketRecver, (LPARAM)&packetRecv);
		if (recvResult == 0) {
			debugLogA("P2P: File transfer connection Error: 0");
			break;
		}
		if (recvResult == SOCKET_ERROR) {
			failed_conn = true;
			debugLogA("P2P: File transfer connection Error: -1");
			break;
		}
		if (recvResult > 0) {
			if (!accepted_file) {
				if (recvResult < 0x100) continue;

				oft2* recv_ft = (oft2*)&packetRecv.buffer[packetRecv.bytesUsed];
				unsigned short pkt_len = _htons(recv_ft->length);

				if (recvResult < pkt_len) continue;
				packetRecv.bytesUsed += pkt_len;

				unsigned short type = _htons(recv_ft->type);
				if (type == 0x0101) {
					debugLogA("P2P: Buddy Ready to begin transfer.");
					oft = (oft2*)mir_realloc(oft, pkt_len);
					memcpy(oft, recv_ft, pkt_len);
					memcpy(oft->icbm_cookie, ft->icbm_cookie, 8);

					int buflen = pkt_len - 0x100 + 64;
					char *buf = (char*)mir_calloc(buflen + 2);
					unsigned short enc;

					ft->pfts.currentFileSize = _htonl(recv_ft->size);
					ft->pfts.totalBytes = _htonl(recv_ft->total_size);
					ft->pfts.currentFileTime = _htonl(recv_ft->mod_time);
					memcpy(buf, recv_ft->filename, buflen);
					enc = _htons(recv_ft->encoding);

					TCHAR *name;
					if (enc == 2) {
						wchar_t* wbuf = (wchar_t*)buf;
						wcs_htons(wbuf);
						for (wchar_t *p = wbuf; *p; ++p) { if (*p == 1) *p = '\\'; }
						name = mir_u2t(wbuf);
					}
					else {
						for (char *p = buf; *p; ++p) { if (*p == 1) *p = '\\'; }
						name = mir_a2t(buf);
					}

					mir_free(buf);

					TCHAR fname[256];
					mir_sntprintf(fname, _T("%s%s"), ft->pfts.tszWorkingDir, name);
					mir_free(name);
					mir_free(ft->pfts.tszCurrentFile);
					ft->pfts.tszCurrentFile = mir_tstrdup(fname);

					ResetEvent(ft->hResumeEvent);
					if (ProtoBroadcastAck(ft->hContact, ACKTYPE_FILE, ACKRESULT_FILERESUME, ft, (LPARAM)&ft->pfts))
						WaitForSingleObject(ft->hResumeEvent, INFINITE);

					if (ft->pfts.tszCurrentFile) {
						TCHAR* dir = get_dir(ft->pfts.tszCurrentFile);
						CreateDirectoryTreeT(dir);
						mir_free(dir);

						oft->type = _htons(ft->pfts.currentFileProgress ? 0x0205 : 0x0202);

						const int flag = ft->pfts.currentFileProgress ? 0 : _O_TRUNC;
						fid = _topen(ft->pfts.tszCurrentFile, _O_CREAT | _O_WRONLY | _O_BINARY | flag, _S_IREAD | _S_IWRITE);

						if (fid < 0) {
							report_file_error(fname);
							break;
						}

						accepted_file = ft->pfts.currentFileProgress == 0;

						if (ft->pfts.currentFileProgress) {
							bool the_same;
							oft->recv_bytes = _htonl(ft->pfts.currentFileProgress);
							oft->recv_checksum = _htonl(aim_oft_checksum_file(ft->pfts.tszCurrentFile));
							the_same = oft->size == oft->recv_bytes && oft->checksum == oft->recv_checksum;
							if (the_same) {
								ft->pfts.totalProgress += ft->pfts.currentFileProgress;
								oft->type = _htons(0x0204);
								_close(fid);

								ProtoBroadcastAck(ft->hContact, ACKTYPE_FILE, ACKRESULT_NEXTFILE, ft, 0);
								++ft->pfts.currentFileNumber;
								ft->pfts.currentFileProgress = 0;
							}
						}
					}
					else {
						oft->type = _htons(0x0204);

						ProtoBroadcastAck(ft->hContact, ACKTYPE_FILE, ACKRESULT_NEXTFILE, ft, 0);
						++ft->pfts.currentFileNumber;
						ft->pfts.currentFileProgress = 0;
					}

					if (Netlib_Send(ft->hConn, (char*)oft, pkt_len, 0) == SOCKET_ERROR)
						break;

					if (ft->pfts.currentFileNumber >= ft->pfts.totalFiles && _htons(oft->type) == 0x0204) {
						failed = false;
						break;
					}
				}
				else if (type == 0x0106) {
					oft = (oft2*)mir_realloc(oft, pkt_len);
					memcpy(oft, recv_ft, pkt_len);

					ft->pfts.currentFileProgress = _htonl(oft->recv_bytes);
					ft->pfts.totalProgress += ft->pfts.currentFileProgress;

					_lseeki64(fid, ft->pfts.currentFileProgress, SEEK_SET);
					accepted_file = true;

					oft->type = _htons(0x0207);
					if (Netlib_Send(ft->hConn, (char*)oft, pkt_len, 0) == SOCKET_ERROR)
						break;
				}
				else break;
			}
			else {
				packetRecv.bytesUsed = packetRecv.bytesAvailable;
				_write(fid, packetRecv.buffer, packetRecv.bytesAvailable);
				ft->pfts.currentFileProgress += packetRecv.bytesAvailable;
				ft->pfts.totalProgress += packetRecv.bytesAvailable;
				ProtoBroadcastAck(ft->hContact, ACKTYPE_FILE, ACKRESULT_DATA, ft, (LPARAM)&ft->pfts);
				if (ft->pfts.currentFileSize == ft->pfts.currentFileProgress) {
					oft->type = _htons(0x0204);
					oft->recv_bytes = _htonl(ft->pfts.currentFileProgress);
					oft->recv_checksum = _htonl(aim_oft_checksum_file(ft->pfts.tszCurrentFile));

					debugLogA("P2P: We got the file successfully");
					Netlib_Send(ft->hConn, (char*)oft, _htons(oft->length), 0);
					if (_htons(oft->num_files_left) == 1) {
						failed = false;
						break;
					}
					else {
						accepted_file = false;
						_close(fid);

						ProtoBroadcastAck(ft->hContact, ACKTYPE_FILE, ACKRESULT_NEXTFILE, ft, 0);
						++ft->pfts.currentFileNumber;
						ft->pfts.currentFileProgress = 0;
					}
				}
			}
		}
	}

	if (accepted_file) _close(fid);
	mir_free(oft);

	ft->success = !failed;
	return failed ? (failed_conn ? 1 : 2) : 0;
}
Exemplo n.º 11
0
int CAimProto::sending_file(file_transfer *ft, HANDLE hServerPacketRecver, NETLIBPACKETRECVER &packetRecv)
{
	debugLogA("P2P: Entered file sending thread.");

	bool failed = true;
	bool failed_conn = false;

	if (!setup_next_file_send(ft)) return 2;

	debugLogA("Sent file information to buddy.");
	//start listen for packets stuff

	for (;;) {
		int recvResult = packetRecv.bytesAvailable - packetRecv.bytesUsed;
		if (recvResult <= 0)
			recvResult = CallService(MS_NETLIB_GETMOREPACKETS, (WPARAM)hServerPacketRecver, (LPARAM)&packetRecv);
		if (recvResult == 0) {
			debugLogA("P2P: File transfer connection Error: 0");
			break;
		}
		if (recvResult == SOCKET_ERROR) {
			failed_conn = true;
			debugLogA("P2P: File transfer connection Error: -1");
			break;
		}
		if (recvResult > 0) {
			if (recvResult < 0x100) continue;

			oft2* recv_ft = (oft2*)&packetRecv.buffer[packetRecv.bytesUsed];

			unsigned short pkt_len = _htons(recv_ft->length);
			if (recvResult < pkt_len) continue;

			packetRecv.bytesUsed += pkt_len;
			unsigned short type = _htons(recv_ft->type);
			if (type == 0x0202 || type == 0x0207) {
				debugLogA("P2P: Buddy Accepts our file transfer.");

				int fid = _topen(ft->pfts.tszCurrentFile, _O_RDONLY | _O_BINARY, _S_IREAD);
				if (fid < 0) {
					report_file_error(ft->pfts.tszCurrentFile);
					return 2;
				}

				if (ft->pfts.currentFileProgress) _lseeki64(fid, ft->pfts.currentFileProgress, SEEK_SET);

				NETLIBSELECT tSelect = { 0 };
				tSelect.cbSize = sizeof(tSelect);
				tSelect.hReadConns[0] = ft->hConn;

				ProtoBroadcastAck(ft->hContact, ACKTYPE_FILE, ACKRESULT_DATA, ft, (LPARAM)&ft->pfts);

				clock_t lNotify = clock();
				for (;;) {
					char buffer[4096];
					int bytes = _read(fid, buffer, sizeof(buffer));
					if (bytes <= 0) break;

					if (Netlib_Send(ft->hConn, buffer, bytes, MSG_NODUMP) <= 0) break;
					ft->pfts.currentFileProgress += bytes;
					ft->pfts.totalProgress += bytes;

					if (clock() >= lNotify) {
						ProtoBroadcastAck(ft->hContact, ACKTYPE_FILE, ACKRESULT_DATA, ft, (LPARAM)&ft->pfts);
						if (CallService(MS_NETLIB_SELECT, 0, (LPARAM)&tSelect)) break;

						lNotify = clock() + 500;
					}
				}
				ProtoBroadcastAck(ft->hContact, ACKTYPE_FILE, ACKRESULT_DATA, ft, (LPARAM)&ft->pfts);
				debugLogA("P2P: Finished sending file bytes.");
				_close(fid);
			}
			else if (type == 0x0204) {
				// Handle file skip case
				if (ft->pfts.currentFileProgress == 0) {
					ft->pfts.totalProgress += ft->pfts.currentFileSize;
				}

				debugLogA("P2P: Buddy says they got the file successfully");
				if ((ft->pfts.currentFileNumber + 1) < ft->pfts.totalFiles) {
					ProtoBroadcastAck(ft->hContact, ACKTYPE_FILE, ACKRESULT_NEXTFILE, ft, 0);
					++ft->pfts.currentFileNumber; ++ft->cf;

					if (!setup_next_file_send(ft)) {
						report_file_error(ft->pfts.tszCurrentFile);
						return 2;
					}
				}
				else {
					failed = _htonl(recv_ft->recv_bytes) != ft->pfts.currentFileSize;
					break;
				}
			}
			else if (type == 0x0205) {
				recv_ft = (oft2*)packetRecv.buffer;
				recv_ft->type = _htons(0x0106);

				ft->pfts.currentFileProgress = _htonl(recv_ft->recv_bytes);
				if (aim_oft_checksum_file(ft->pfts.tszCurrentFile, ft->pfts.currentFileProgress) != _htonl(recv_ft->recv_checksum)) {
					ft->pfts.currentFileProgress = 0;
					recv_ft->recv_bytes = 0;
				}

				debugLogA("P2P: Buddy wants us to start sending at a specified file point. (%I64u)", ft->pfts.currentFileProgress);
				if (Netlib_Send(ft->hConn, (char*)recv_ft, _htons(recv_ft->length), 0) <= 0) break;

				ft->pfts.totalProgress += ft->pfts.currentFileProgress;
				ProtoBroadcastAck(ft->hContact, ACKTYPE_FILE, ACKRESULT_DATA, ft, (LPARAM)&ft->pfts);
			}
		}
	}

	ft->success = !failed;
	return failed ? (failed_conn ? 1 : 2) : 0;
}
Exemplo n.º 12
0
Arquivo: dired.c Projeto: stanis/emacs
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,
			      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 (SDATA (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, SDATA (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);
}
Exemplo n.º 13
0
static AudioContext
initialize_audio_port (AudioContext desc)
{
  /* we can't use the same port for mono and stereo */
  static AudioContextRec mono_port_state
    = { { 0, 0, 0, 0 },
	{ (ALport) 0, AFunknown, 1, 0 },
	{ (void *) 0, (unsigned long) 0 } };
#if HAVE_STEREO
  static AudioContextRec stereo_port_state
    = { { 0, 0, 0, 0 },
	{ (ALport) 0, AFunknown, 2, 0 },
	{ (void *) 0, (unsigned long) 0 } };
  static AudioContext return_ac;

  switch (desc->ac_nchan)
    {
    case 1:  return_ac = & mono_port_state; break;
    case 2:  return_ac = & stereo_port_state; break;
    default: return (AudioContext) 0;
    }
#else /* not HAVE_STEREO */
  static AudioContext return_ac = & mono_port_state;
#endif /* not HAVE_STEREO */

  return_ac->device = desc->device;
  return_ac->buffer = desc->buffer;
  return_ac->ac_format = desc->ac_format;
  return_ac->ac_queue_size = desc->ac_queue_size;

  if (return_ac->ac_port==(ALport) 0)
    {
      if ((open_audio_port (return_ac, desc))==-1)
	{
	  report_file_error ("Open audio port", Qnil);
	  return (AudioContext) 0;
	}
    }
  else
    {
      ALconfig config = ALgetconfig (return_ac->ac_port);
      int changed = 0;
      long params[2];

      params[0] = AL_OUTPUT_RATE;
      ALgetparams (return_ac->ac_device, params, 2);
      return_ac->ac_output_rate = params[1];

      if (return_ac->ac_output_rate != desc->ac_output_rate)
	{
	  return_ac->ac_output_rate = params[1] = desc->ac_output_rate;
	  ALsetparams (return_ac->ac_device, params, 2);
	}
      if ((changed = set_output_format (config, return_ac->ac_format))==-1)
	return (AudioContext) 0;
      return_ac->ac_format = desc->ac_format;
      if (changed)
	ALsetconfig (return_ac->ac_port, config);
    }
  return_ac->ac_write_chunk_function = desc->ac_write_chunk_function;
  get_current_volumes (& return_ac->device);
  if (return_ac->ac_left_speaker_gain != desc->ac_left_speaker_gain
      || return_ac->ac_right_speaker_gain != desc->ac_right_speaker_gain)
    adjust_audio_volume (& desc->device);
  return return_ac;
}
Exemplo n.º 14
0
static Lisp_Object
get_object_file_name (Lisp_Object filepos)
{
  REGISTER int fd;
  REGISTER Ibyte *name_nonreloc = 0;
  EMACS_INT position;
  Lisp_Object file, tem;
  Lisp_Object name_reloc = Qnil;
  int standard_doc_file = 0;

  if (FIXNUMP (filepos))
    {
      file = Vinternal_doc_file_name;
      standard_doc_file = 1;
      position = XFIXNUM (filepos);
    }
  else if (CONSP (filepos) && FIXNUMP (XCDR (filepos)))
    {
      file = XCAR (filepos);
      position = XFIXNUM (XCDR (filepos));
      if (position < 0)
	position = - position;
    }
  else
    return Qnil;

  if (!STRINGP (file))
    return Qnil;

  /* Put the file name in NAME as a C string.
     If it is relative, combine it with Vdoc_directory.  */

  tem = Ffile_name_absolute_p (file);
  if (NILP (tem))
    {
      Bytecount minsize;
      /* XEmacs: Move this check here.  OK if called during loadup to
	 load byte code instructions. */
      if (!STRINGP (Vdoc_directory))
	return Qnil;

      minsize = XSTRING_LENGTH (Vdoc_directory);
      /* sizeof ("../lib-src/") == 12 */
      if (minsize < 12)
	minsize = 12;
      name_nonreloc = alloca_ibytes (minsize + XSTRING_LENGTH (file) + 8);
      string_join (name_nonreloc, Vdoc_directory, file);
    }
  else
    name_reloc = file;

  fd = qxe_open (name_nonreloc ? name_nonreloc :
		 XSTRING_DATA (name_reloc), O_RDONLY | OPEN_BINARY, 0);
  if (fd < 0)
    {
      if (purify_flag)
	{
	    /* sizeof ("../lib-src/") == 12 */
	  name_nonreloc = alloca_ibytes (12 + XSTRING_LENGTH (file) + 8);
	  /* Preparing to dump; DOC file is probably not installed.
	     So check in ../lib-src. */
	  qxestrcpy_ascii (name_nonreloc, "../lib-src/");
	  qxestrcat (name_nonreloc, XSTRING_DATA (file));

	  fd = qxe_open (name_nonreloc, O_RDONLY | OPEN_BINARY, 0);
	}

      if (fd < 0)
	report_file_error ("Cannot open doc string file",
			   name_nonreloc ? build_istring (name_nonreloc) :
			   name_reloc);
    }

  tem = extract_object_file_name (fd, position, name_nonreloc, name_reloc,
			      standard_doc_file);
  retry_close (fd);

  if (!STRINGP (tem))
    signal_error_1 (Qinvalid_byte_code, tem);

  return tem;
}
Exemplo n.º 15
0
/* if we can't determine it, we will return true */
static int
is_gui_app (char *exe)
{
  HANDLE hImage;

  DWORD  bytes;
  DWORD  iSection;
  DWORD  SectionOffset;
  DWORD  CoffHeaderOffset;
  DWORD  MoreDosHeader[16];
  CHAR   *file;
  size_t nlen;

  ULONG  ntSignature;

  IMAGE_DOS_HEADER      image_dos_header;
  IMAGE_FILE_HEADER     image_file_header;
  IMAGE_OPTIONAL_HEADER image_optional_header;
  IMAGE_SECTION_HEADER  image_section_header;

  /*
   *  Open the reference file.
  */
  nlen = strlen (exe);
  file = exe;
  if (nlen > 2) {
    if (exe[0] == '"') {
      /* remove quotes */
      nlen -= 2;
      file = malloc ((nlen + 1) * sizeof (char));
      memcpy (file, &exe[1], nlen);
      file [nlen] = '\0';
    }
  }
  hImage = CreateFile(file,
                      GENERIC_READ,
                      FILE_SHARE_READ,
                      NULL,
                      OPEN_EXISTING,
                      FILE_ATTRIBUTE_NORMAL,
                      NULL);

  if (file != exe) {
    free (file);
  }

  if (INVALID_HANDLE_VALUE == hImage)
    {
      report_file_error ("Could not open exe: ", Qnil);
      report_file_error (exe, Qnil);
      report_file_error ("\n", Qnil);
      CloseHandle (hImage);
      return -1;
    }

  /*
   *  Read the MS-DOS image header.
   */
  ReadBytes(hImage, &image_dos_header, sizeof(IMAGE_DOS_HEADER));

  if (IMAGE_DOS_SIGNATURE != image_dos_header.e_magic)
    {
      report_file_error("Sorry, I do not understand this file.\n", Qnil);
      CloseHandle (hImage);
      return -1;
    }

  /*
   *  Read more MS-DOS header.       */
  ReadBytes(hImage, MoreDosHeader, sizeof(MoreDosHeader));
   /*
   *  Get actual COFF header.
   */
  CoffHeaderOffset = AbsoluteSeek(hImage, image_dos_header.e_lfanew) +
                     sizeof(ULONG);
  if (CoffHeaderOffset < 0) {
    CloseHandle (hImage);
    return -1;
  }

  ReadBytes (hImage, &ntSignature, sizeof(ULONG));

  if (IMAGE_NT_SIGNATURE != ntSignature)
    {
      report_file_error ("Missing NT signature. Unknown file type.\n", Qnil);
      CloseHandle (hImage);
      return -1;
    }

  SectionOffset = CoffHeaderOffset + IMAGE_SIZEOF_FILE_HEADER +
    IMAGE_SIZEOF_NT_OPTIONAL_HEADER;

  ReadBytes(hImage, &image_file_header, IMAGE_SIZEOF_FILE_HEADER);

  /*
   *  Read optional header.
   */
  ReadBytes(hImage,
            &image_optional_header,
            IMAGE_SIZEOF_NT_OPTIONAL_HEADER);

  CloseHandle (hImage);

  switch (image_optional_header.Subsystem)
    {
    case IMAGE_SUBSYSTEM_UNKNOWN:
        return 1;
        break;

    case IMAGE_SUBSYSTEM_NATIVE:
        return 1;
        break;

    case IMAGE_SUBSYSTEM_WINDOWS_GUI:
        return 1;
        break;

    case IMAGE_SUBSYSTEM_WINDOWS_CUI:
        return 0;
        break;

    case IMAGE_SUBSYSTEM_OS2_CUI:
        return 0;
        break;

    case IMAGE_SUBSYSTEM_POSIX_CUI:
        return 0;
        break;

    default:
        /* Unknown, return GUI app to be preservative: if yes, it will be
           correctly launched, if no, it will be launched, and a console will
           be also displayed, which is not a big deal */
        return 1;
        break;
    }

}
Exemplo n.º 16
0
/* This compares two directory listings in case of a `write' event for
   a directory.  Generate resulting file notification events.  The old
   directory listing is retrieved from watch_object, it will be
   replaced by the new directory listing at the end of this
   function.  */
static void
kqueue_compare_dir_list
(Lisp_Object watch_object)
{
  Lisp_Object dir, pending_dl, deleted_dl;
  Lisp_Object old_directory_files, old_dl, new_directory_files, new_dl, dl;

  dir = XCAR (XCDR (watch_object));
  pending_dl = Qnil;
  deleted_dl = Qnil;

  old_directory_files = Fnth (make_number (4), watch_object);
  old_dl = kqueue_directory_listing (old_directory_files);

  /* When the directory is not accessible anymore, it has been deleted.  */
  if (NILP (Ffile_directory_p (dir))) {
    kqueue_generate_event (watch_object, Fcons (Qdelete, Qnil), dir, Qnil);
    return;
  }
  new_directory_files =
    directory_files_internal (dir, Qnil, Qnil, Qnil, 1, Qnil);
  new_dl = kqueue_directory_listing (new_directory_files);

  /* Parse through the old list.  */
  dl = old_dl;
  while (1) {
    Lisp_Object old_entry, new_entry, dl1;
    if (NILP (dl))
      break;

    /* Search for an entry with the same inode.  */
    old_entry = XCAR (dl);
    new_entry = assq_no_quit (XCAR (old_entry), new_dl);
    if (! NILP (Fequal (old_entry, new_entry))) {
      /* Both entries are identical.  Nothing to do.  */
      new_dl = Fdelq (new_entry, new_dl);
      goto the_end;
    }

    /* Both entries have the same inode.  */
    if (! NILP (new_entry)) {
      /* Both entries have the same file name.  */
      if (strcmp (SSDATA (XCAR (XCDR (old_entry))),
		  SSDATA (XCAR (XCDR (new_entry)))) == 0) {
	/* Modification time has been changed, the file has been written.  */
	if (NILP (Fequal (Fnth (make_number (2), old_entry),
			  Fnth (make_number (2), new_entry))))
	  kqueue_generate_event
	    (watch_object, Fcons (Qwrite, Qnil), XCAR (XCDR (old_entry)), Qnil);
	/* Status change time has been changed, the file attributes
	   have changed.  */
	  if (NILP (Fequal (Fnth (make_number (3), old_entry),
			    Fnth (make_number (3), new_entry))))
	  kqueue_generate_event
	    (watch_object, Fcons (Qattrib, Qnil),
	     XCAR (XCDR (old_entry)), Qnil);

      } else {
	/* The file has been renamed.  */
	kqueue_generate_event
	  (watch_object, Fcons (Qrename, Qnil),
	   XCAR (XCDR (old_entry)), XCAR (XCDR (new_entry)));
	deleted_dl = Fcons (new_entry, deleted_dl);
      }
      new_dl = Fdelq (new_entry, new_dl);
      goto the_end;
    }

    /* Search, whether there is a file with the same name but another
       inode.  */
    for (dl1 = new_dl; ! NILP (dl1); dl1 = XCDR (dl1)) {
      new_entry = XCAR (dl1);
      if (strcmp (SSDATA (XCAR (XCDR (old_entry))),
		  SSDATA (XCAR (XCDR (new_entry)))) == 0) {
	pending_dl = Fcons (new_entry, pending_dl);
	new_dl = Fdelq (new_entry, new_dl);
	goto the_end;
      }
    }

    /* Check, whether this a pending file.  */
    new_entry = assq_no_quit (XCAR (old_entry), pending_dl);

    if (NILP (new_entry)) {
      /* Check, whether this is an already deleted file (by rename).  */
      for (dl1 = deleted_dl; ! NILP (dl1); dl1 = XCDR (dl1)) {
	new_entry = XCAR (dl1);
	if (strcmp (SSDATA (XCAR (XCDR (old_entry))),
		    SSDATA (XCAR (XCDR (new_entry)))) == 0) {
	  deleted_dl = Fdelq (new_entry, deleted_dl);
	  goto the_end;
	}
      }
      /* The file has been deleted.  */
      kqueue_generate_event
	(watch_object, Fcons (Qdelete, Qnil), XCAR (XCDR (old_entry)), Qnil);

    } else {
      /* The file has been renamed.  */
      kqueue_generate_event
	(watch_object, Fcons (Qrename, Qnil),
	 XCAR (XCDR (old_entry)), XCAR (XCDR (new_entry)));
      pending_dl = Fdelq (new_entry, pending_dl);
    }

  the_end:
    dl = XCDR (dl);
    old_dl = Fdelq (old_entry, old_dl);
  }

  /* Parse through the resulting new list.  */
  dl = new_dl;
  while (1) {
    Lisp_Object entry;
    if (NILP (dl))
      break;

    /* A new file has appeared.  */
    entry = XCAR (dl);
    kqueue_generate_event
      (watch_object, Fcons (Qcreate, Qnil), XCAR (XCDR (entry)), Qnil);

    /* Check size of that file.  */
    Lisp_Object size = Fnth (make_number (4), entry);
    if (FLOATP (size) || (XINT (size) > 0))
      kqueue_generate_event
	(watch_object, Fcons (Qwrite, Qnil), XCAR (XCDR (entry)), Qnil);

    dl = XCDR (dl);
    new_dl = Fdelq (entry, new_dl);
  }

  /* Parse through the resulting pending_dl list.  */
  dl = pending_dl;
  while (1) {
    Lisp_Object entry;
    if (NILP (dl))
      break;

    /* A file is still pending.  Assume it was a write.  */
    entry = XCAR (dl);
    kqueue_generate_event
      (watch_object, Fcons (Qwrite, Qnil), XCAR (XCDR (entry)), Qnil);

    dl = XCDR (dl);
    pending_dl = Fdelq (entry, pending_dl);
  }

  /* At this point, old_dl, new_dl and pending_dl shall be empty.
     deleted_dl might not be empty when there was a rename to a
     nonexistent file.  Let's make a check for this (might be removed
     once the code is stable).  */
  if (! NILP (old_dl))
    report_file_error ("Old list not empty", old_dl);
  if (! NILP (new_dl))
    report_file_error ("New list not empty", new_dl);
  if (! NILP (pending_dl))
    report_file_error ("Pending events list not empty", pending_dl);
  //  if (! NILP (deleted_dl))
  //    report_file_error ("Deleted events list not empty", deleted_dl);

  /* Replace old directory listing with the new one.  */
  XSETCDR (Fnthcdr (make_number (3), watch_object),
	   Fcons (new_directory_files, Qnil));
  return;
}
Exemplo n.º 17
0
static WIN32_FIND_DATA *
mswindows_get_files (char *dirfile, int nowild, Lisp_Object pattern,
		     int hide_dot, int hide_system, int *nfiles)
{
  WIN32_FIND_DATA		*files;
  int				array_size;
  struct re_pattern_buffer	*bufp = NULL;
  int				findex, len;
  char				win32pattern[MAXNAMLEN+3];
  HANDLE			fh;
  int				errm;

  /*
   * Much of the following code and comments were taken from dired.c.
   * Yes, this is something of a waste, but we want speed, speed, SPEED.
   */
  files = NULL;
  array_size = *nfiles = 0;
  while (1)
    {
      if (!NILP(pattern))
	{
	  /* PATTERN might be a flawed regular expression.  Rather than
	     catching and signalling our own errors, we just call
	     compile_pattern to do the work for us.  */
	  bufp = compile_pattern (pattern, 0, Qnil, 0, ERROR_ME);
	}
      /* Now *bufp is the compiled form of PATTERN; don't call anything
	 which might compile a new regexp until we're done with the loop! */

      /* Initialize file info array */
      array_size = 100;		/* initial size */
      files = xmalloc(array_size * sizeof (WIN32_FIND_DATA));

      /* for Win32, we need to insure that the pathname ends with "\*". */
      strcpy (win32pattern, dirfile);
      if (!nowild)
	{
	  len = strlen (win32pattern) - 1;
	  if (!IS_DIRECTORY_SEP (win32pattern[len]))
	    strcat (win32pattern, "\\");
	  strcat (win32pattern, "*");
	}

      /*
       * Here, we use FindFirstFile()/FindNextFile() instead of opendir(),
       * xemacs_stat(), & friends, because xemacs_stat() is VERY expensive in
       * terms of time.  Hence, we take the time to write complicated
       * Win32-specific code, instead of simple Unix-style stuff.
       */
      findex = 0;
      fh = INVALID_HANDLE_VALUE;
      errm = SetErrorMode (SEM_FAILCRITICALERRORS
			   | SEM_NOOPENFILEERRORBOX);

      while (1)
	{
	  int		len;
	  char	*filename;
	  int		result;

	  if (fh == INVALID_HANDLE_VALUE)
	    {
	      fh = FindFirstFile(win32pattern, &files[findex]);
	      if (fh == INVALID_HANDLE_VALUE)
		{
		  SetErrorMode (errm);
		  report_file_error ("Opening directory",
				     list1(build_string(dirfile)));
		}
	    }
	  else
	    {
	      if (!FindNextFile(fh, &files[findex]))
		{
		  if (GetLastError() == ERROR_NO_MORE_FILES)
		    {
		      break;
		    }
		  FindClose(fh);
		  SetErrorMode (errm);
		  report_file_error ("Reading directory",
				     list1(build_string(dirfile)));
		}
	    }

	  filename = files[findex].cFileName;
	  if (!NILP(Vmswindows_downcase_file_names))
	  {
	      strlwr(filename);
	  }
	  len = strlen(filename);
	  result = (NILP(pattern)
		    || (0 <= re_search (bufp, filename, 
					len, 0, len, 0)));
	  if (result)
	    {
	      if ( ! (filename[0] == '.' &&
		      ((hide_system && (filename[1] == '\0' ||
					(filename[1] == '.' &&
					 filename[2] == '\0'))) ||
		       hide_dot)))
		{
		  if (++findex >= array_size)
		    {
		      array_size = findex * 2;
		      files = xrealloc(files,
				       array_size * sizeof(WIN32_FIND_DATA));
		    }
		}
	    }
	}
      if (fh != INVALID_HANDLE_VALUE)
	{
	  FindClose (fh);
	}
      *nfiles = findex;
      break;
    }

  SetErrorMode (errm);
  return (files);
}