⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 rtapelib.c

📁 gnu tar 源码包。 tar 软件是 Unix 系统下的一个打包软件
💻 C
📖 第 1 页 / 共 2 页
字号:
  for (remote_pipe_number = 0;       remote_pipe_number < MAXUNIT;       remote_pipe_number++)    if (READ_SIDE (remote_pipe_number) == -1	&& WRITE_SIDE (remote_pipe_number) == -1)      break;  if (remote_pipe_number == MAXUNIT)    {      errno = EMFILE;      return -1;    }  /* Pull apart the system and device, and optional user.  */  {    char *cursor;    file_name_copy = xstrdup (file_name);    remote_host = file_name_copy;    remote_user = 0;    remote_file = 0;    for (cursor = file_name_copy; *cursor; cursor++)      switch (*cursor)	{	default:	  break;	case '\n':	  /* Do not allow newlines in the file_name, since the protocol	     uses newline delimiters.  */	  free (file_name_copy);	  errno = ENOENT;	  return -1;	case '@':	  if (!remote_user)	    {	      remote_user = remote_host;	      *cursor = '\0';	      remote_host = cursor + 1;	    }	  break;	case ':':	  if (!remote_file)	    {	      *cursor = '\0';	      remote_file = cursor + 1;	    }	  break;	}  }  /* FIXME: Should somewhat validate the decoding, here.  */  if (remote_user && *remote_user == '\0')    remote_user = 0;#if WITH_REXEC  /* Execute the remote command using rexec.  */  READ_SIDE (remote_pipe_number) = _rmt_rexec (remote_host, remote_user);  if (READ_SIDE (remote_pipe_number) < 0)    {      int e = errno;      free (file_name_copy);      errno = e;      return -1;    }  WRITE_SIDE (remote_pipe_number) = READ_SIDE (remote_pipe_number);#else /* not WITH_REXEC */  {    const char *remote_shell_basename;    pid_t status;    /* Identify the remote command to be executed.  */    if (!remote_shell)      {#ifdef REMOTE_SHELL	remote_shell = REMOTE_SHELL;#else	free (file_name_copy);	errno = EIO;	return -1;#endif      }    remote_shell_basename = last_component (remote_shell);    /* Set up the pipes for the `rsh' command, and fork.  */    if (pipe (to_remote[remote_pipe_number]) == -1	|| pipe (from_remote[remote_pipe_number]) == -1)      {	int e = errno;	free (file_name_copy);	errno = e;	return -1;      }    status = fork ();    if (status == -1)      {	int e = errno;	free (file_name_copy);	errno = e;	return -1;      }    if (status == 0)      {	/* Child.  */	close (STDIN_FILENO);	dup (to_remote[remote_pipe_number][PREAD]);	close (to_remote[remote_pipe_number][PREAD]);	close (to_remote[remote_pipe_number][PWRITE]);	close (STDOUT_FILENO);	dup (from_remote[remote_pipe_number][PWRITE]);	close (from_remote[remote_pipe_number][PREAD]);	close (from_remote[remote_pipe_number][PWRITE]);	sys_reset_uid_gid ();	if (remote_user)	  execl (remote_shell, remote_shell_basename, remote_host,		 "-l", remote_user, rmt_command, (char *) 0);	else	  execl (remote_shell, remote_shell_basename, remote_host,		 rmt_command, (char *) 0);	/* Bad problems if we get here.  */	/* In a previous version, _exit was used here instead of exit.  */	error (EXIT_ON_EXEC_ERROR, errno, _("Cannot execute remote shell"));      }    /* Parent.  */    close (from_remote[remote_pipe_number][PWRITE]);    close (to_remote[remote_pipe_number][PREAD]);  }#endif /* not WITH_REXEC */  /* Attempt to open the tape device.  */  {    size_t remote_file_len = strlen (remote_file);    char *command_buffer = xmalloc (remote_file_len + 1000);    sprintf (command_buffer, "O%s\n", remote_file);    encode_oflag (command_buffer + remote_file_len + 2, open_mode);    strcat (command_buffer, "\n");    if (do_command (remote_pipe_number, command_buffer) == -1	|| get_status (remote_pipe_number) == -1)      {	int e = errno;	free (command_buffer);	free (file_name_copy);	_rmt_shutdown (remote_pipe_number, e);	return -1;      }    free (command_buffer);  }  free (file_name_copy);  return remote_pipe_number + bias;}/* Close remote tape connection HANDLE and shut down.  Return 0 if   successful, -1 on error.  */intrmt_close__ (int handle){  long int status;  if (do_command (handle, "C\n") == -1)    return -1;  status = get_status (handle);  _rmt_shutdown (handle, errno);  return status;}/* Read up to LENGTH bytes into BUFFER from remote tape connection HANDLE.   Return the number of bytes read on success, SAFE_READ_ERROR on error.  */size_trmt_read__ (int handle, char *buffer, size_t length){  char command_buffer[COMMAND_BUFFER_SIZE];  size_t status;  size_t rlen;  size_t counter;  sprintf (command_buffer, "R%lu\n", (unsigned long) length);  if (do_command (handle, command_buffer) == -1      || (status = get_status (handle)) == SAFE_READ_ERROR)    return SAFE_READ_ERROR;  for (counter = 0; counter < status; counter += rlen, buffer += rlen)    {      rlen = safe_read (READ_SIDE (handle), buffer, status - counter);      if (rlen == SAFE_READ_ERROR || rlen == 0)	{	  _rmt_shutdown (handle, EIO);	  return SAFE_READ_ERROR;	}    }  return status;}/* Write LENGTH bytes from BUFFER to remote tape connection HANDLE.   Return the number of bytes written.  */size_trmt_write__ (int handle, char *buffer, size_t length){  char command_buffer[COMMAND_BUFFER_SIZE];  RETSIGTYPE (*pipe_handler) ();  size_t written;  sprintf (command_buffer, "W%lu\n", (unsigned long) length);  if (do_command (handle, command_buffer) == -1)    return 0;  pipe_handler = signal (SIGPIPE, SIG_IGN);  written = full_write (WRITE_SIDE (handle), buffer, length);  signal (SIGPIPE, pipe_handler);  if (written == length)    {      long int r = get_status (handle);      if (r < 0)	return 0;      if (r == length)	return length;      written = r;    }  /* Write error.  */  _rmt_shutdown (handle, EIO);  return written;}/* Perform an imitation lseek operation on remote tape connection   HANDLE.  Return the new file offset if successful, -1 if on error.  */off_trmt_lseek__ (int handle, off_t offset, int whence){  char command_buffer[COMMAND_BUFFER_SIZE];  char operand_buffer[UINTMAX_STRSIZE_BOUND];  uintmax_t u = offset < 0 ? - (uintmax_t) offset : (uintmax_t) offset;  char *p = operand_buffer + sizeof operand_buffer;  *--p = 0;  do    *--p = '0' + (int) (u % 10);  while ((u /= 10) != 0);  if (offset < 0)    *--p = '-';  switch (whence)    {    case SEEK_SET: whence = 0; break;    case SEEK_CUR: whence = 1; break;    case SEEK_END: whence = 2; break;    default: abort ();    }  sprintf (command_buffer, "L%s\n%d\n", p, whence);  if (do_command (handle, command_buffer) == -1)    return -1;  return get_status_off (handle);}/* Perform a raw tape operation on remote tape connection HANDLE.   Return the results of the ioctl, or -1 on error.  */intrmt_ioctl__ (int handle, int operation, char *argument){  switch (operation)    {    default:      errno = EOPNOTSUPP;      return -1;#ifdef MTIOCTOP    case MTIOCTOP:      {	char command_buffer[COMMAND_BUFFER_SIZE];	char operand_buffer[UINTMAX_STRSIZE_BOUND];	uintmax_t u = (((struct mtop *) argument)->mt_count < 0		       ? - (uintmax_t) ((struct mtop *) argument)->mt_count		       : (uintmax_t) ((struct mtop *) argument)->mt_count);	char *p = operand_buffer + sizeof operand_buffer;        *--p = 0;	do	  *--p = '0' + (int) (u % 10);	while ((u /= 10) != 0);	if (((struct mtop *) argument)->mt_count < 0)	  *--p = '-';	/* MTIOCTOP is the easy one.  Nothing is transferred in binary.  */	sprintf (command_buffer, "I%d\n%s\n",		 ((struct mtop *) argument)->mt_op, p);	if (do_command (handle, command_buffer) == -1)	  return -1;	return get_status (handle);      }#endif /* MTIOCTOP */#ifdef MTIOCGET    case MTIOCGET:      {	ssize_t status;	size_t counter;	/* Grab the status and read it directly into the structure.  This	   assumes that the status buffer is not padded and that 2 shorts	   fit in a long without any word alignment problems; i.e., the	   whole struct is contiguous.  NOTE - this is probably NOT a good	   assumption.  */	if (do_command (handle, "S") == -1	    || (status = get_status (handle), status == -1))	  return -1;	for (; status > 0; status -= counter, argument += counter)	  {	    counter = safe_read (READ_SIDE (handle), argument, status);	    if (counter == SAFE_READ_ERROR || counter == 0)	      {		_rmt_shutdown (handle, EIO);		return -1;	      }	  }	/* Check for byte position.  mt_type (or mt_model) is a small integer	   field (normally) so we will check its magnitude.  If it is larger	   than 256, we will assume that the bytes are swapped and go through	   and reverse all the bytes.  */	if (((struct mtget *) argument)->MTIO_CHECK_FIELD < 256)	  return 0;	for (counter = 0; counter < status; counter += 2)	  {	    char copy = argument[counter];	    argument[counter] = argument[counter + 1];	    argument[counter + 1] = copy;	  }	return 0;      }#endif /* MTIOCGET */    }}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -