Пример #1
0
static int chunk_wrapper(lua_State* L)
{
	char cwd[PATH_MAX];
	const char* filename;
	char* ptr;
	int i, args;

	args = lua_gettop(L);

	/* Remember the current _SCRIPT and working directory so I can
	 * restore them after this new chunk has been run. */

	do_getcwd(cwd, PATH_MAX);
	lua_getglobal(L, "_SCRIPT");
	lua_getglobal(L, "_SCRIPT_DIR");

	/* Set the new _SCRIPT variable */

	lua_pushvalue(L, lua_upvalueindex(1));
	lua_setglobal(L, "_SCRIPT");

	/* And the new _SCRIPT_DIR variable (const cheating) */

	filename = lua_tostring(L, lua_upvalueindex(1));
	ptr = strrchr(filename, '/');
	if (ptr) *ptr = '\0';
	lua_pushstring(L, filename);
	lua_setglobal(L, "_SCRIPT_DIR");

	/* And make that the CWD (and fix the const cheat) */

	if (filename[0] != '$') {
		do_chdir(L, filename);
	}
	if (ptr) *ptr = '/';

	/* Move the function's arguments to the top of the stack and
	 * execute the function created by luaL_loadfile() */

	lua_pushvalue(L, lua_upvalueindex(2));
	for (i = 1; i <= args; ++i) {
		lua_pushvalue(L, i);
	}

	lua_call(L, args, LUA_MULTRET);

	/* Finally, restore the previous _SCRIPT variable and working directory
	 * before returning control to the previously executing script. */

	do_chdir(L, cwd);
	lua_pushvalue(L, args + 1);
	lua_setglobal(L, "_SCRIPT");
	lua_pushvalue(L, args + 2);
	lua_setglobal(L, "_SCRIPT_DIR");

	return lua_gettop(L) - args - 2;
}
Пример #2
0
void* func_msg(void* arg)
{
	struct thread_info* args = arg;
//	struct sockaddr_in client;
	int sock = args->sock;
	int read_n, errcnt = 0;
	ftp_rqt request;


//	printf("in thread\n");
//	fprintf(stderr, "sock: %d\n", sock);
	while (true) {

		memset(&request, 0, RQT_LEN);
		read_n = recv(sock, (char*)&request, RQT_LEN, 0);

		if (read_n < 0) {
			errcnt ++;
			if (errcnt > 10)
				break ;
			continue ;
		}
		if (read_n == 0) {
			fprintf(stderr, "quit");
			break ; 
		}

	//	printf("msg: %d; read_n: %d\n", request.type, read_n);

		if (request.type == CMD_CLOSE)
			break;

		else if (request.type == CMD_CD) 
			do_chdir(&request, sock);

		else if (request.type == CMD_MKDIR)
			do_mkdir(&request, sock);

		else if (request.type == CMD_RMDIR)
			do_rmdir(&request, sock);

		else if (request.type == CMD_LS)
			do_lsdir(&request, sock);

		else if (request.type == CMD_GET) {
			do_get(&request, sock);
			break;
		}

		else if (request.type == CMD_PUT) {
			printf("put\n");
			do_put(&request, sock);
			break;
		}

//		send(sock, CONFIRM, strlen(CONFIRM)+1, 0);
	}

	thread_end(args);
}
Пример #3
0
/*
 * Archive names specified in file.
 *
 * Unless --null was specified, a line containing exactly "-C" will
 * cause the next line to be a directory to pass to chdir().  If
 * --null is specified, then a line "-C" is just another filename.
 */
static void
archive_names_from_file(struct bsdtar *bsdtar, struct archive *a)
{
	struct lafe_line_reader *lr;
	const char *line;

	bsdtar->next_line_is_dir = 0;

	lr = lafe_line_reader(bsdtar->names_from_file, bsdtar->option_null);
	while ((line = lafe_line_reader_next(lr)) != NULL) {
		if (bsdtar->next_line_is_dir) {
			if (*line != '\0')
				set_chdir(bsdtar, line);
			else {
				lafe_warnc(0,
				    "Meaningless argument for -C: ''");
				bsdtar->return_value = 1;
			}
			bsdtar->next_line_is_dir = 0;
		} else if (!bsdtar->option_null && strcmp(line, "-C") == 0)
			bsdtar->next_line_is_dir = 1;
		else {
			if (*line != '/')
				do_chdir(bsdtar); /* Handle a deferred -C */
			write_hierarchy(bsdtar, a, line);
		}
	}
	lafe_line_reader_free(lr);
	if (bsdtar->next_line_is_dir)
		lafe_errc(1, errno,
		    "Unexpected end of filename list; "
		    "directory expected after -C");
}
Пример #4
0
int main(int argc, char* argv[])
{
  const char* ip;
  const char* tmp;
  
  if (argc < 2) die1(1, "usage: relay-ctrl-check program [arguments]\n");
  log_ips = getenv("RELAY_CTRL_LOG_IPS") != 0;
  log_env = getenv("RELAY_CTRL_LOG_ENV") != 0;
  if (getenv("RELAYCLIENT") == 0) {
    expiry = 0;
    if ((tmp = getenv("RELAY_CTRL_EXPIRY")) != 0) expiry = atol(tmp);
    if (expiry <= 0) expiry = 900;
    if ((rc = getenv("RELAY_CTRL_RELAYCLIENT")) == 0) rc = "";
    if ((ip = getenv("TCPREMOTEIP")) == 0)
      warn1("$TCPREMOTEIP not set, not checking IP");
    else if (do_chdir(0))
      stat_ip(ip);
  }
  else {
    if (log_ips)
      msg1("$RELAYCLIENT already set, not checking IP");
  }
  execvp(argv[1], argv+1);
  die1(111, "execution of program failed!\n");
  return 111;
  argc = 0;
}
Пример #5
0
static int sys_chdir(argstr_t *arg)
{
    argstr_t        kern_args;
    char            *path;
    int             err;
    
    if ((err = copy_from_user(&kern_args, arg, sizeof(argstr_t))) < 0) {
        curthr->kt_errno = -err;
        return -1;
    }
    
    path = user_strdup(&kern_args);
    if (!path) {
        curthr->kt_errno = EINVAL;
        return -1;
    }
    
    err = do_chdir(path);
    kfree(path);
    
    if (err < 0) {
        curthr->kt_errno = -err;
        return -1;
    } else return err;
}
Пример #6
0
static int
archive_names_from_file_helper(struct bsdtar *bsdtar, const char *line)
{
	if (bsdtar->next_line_is_dir) {
		set_chdir(bsdtar, line);
		bsdtar->next_line_is_dir = 0;
	} else if (!bsdtar->option_null && strcmp(line, "-C") == 0)
		bsdtar->next_line_is_dir = 1;
	else {
		if (*line != '/')
			do_chdir(bsdtar); /* Handle a deferred -C */
		write_hierarchy(bsdtar, bsdtar->archive, line);
	}
	return (0);
}
Пример #7
0
int os_chdir(lua_State* L)
{
	const char* path = luaL_checkstring(L, 1);

	int z = do_chdir(L, path);
	if (!z)
	{
		lua_pushnil(L);
		lua_pushfstring(L, "unable to switch to directory '%s'", path);
		return 2;
	}
	else
	{
		lua_pushboolean(L, 1);
		return 1;
	}
}
Пример #8
0
int main(int argv, char* args[]){

	disk = open("/dev/fd0",O_RDWR);
	if (argv > 1){
		if (strcmp(format, args[1]) == 0)
			do_format();
		else if (strcmp(mkdir, args[1]) == 0){
			if (argv > 2)
				do_mkdir(args[2]);
			else 
				printf("Usage: mkdir dir\n");
		}
		else if (strcmp(chdir, args[1]) == 0){
			if (argv > 2)
				do_chdir(args[2]);
			else 
				printf("Usage: chdir dir\n");
		}
		else if (strcmp(copy, args[1]) == 0) {
			do_copy(args[2], args[3], args[4]);
		}
		else if (strcmp(dir, args[1]) == 0)
			do_dir(args[2]);
		else if (strcmp("info", args[1]) == 0){
			info(args[2]);
			}
		else if (strcmp("freeblock", args[1]) == 0)
			free_block();
		else if (strcmp("checkblock", args[1]) == 0)
			check_block(args[2]);



		else
			printf("Unknown dtool command.\n");



	}


	return 0;
}
Пример #9
0
static int
archive_names_from_file_helper(struct bsdtar *bsdtar, const char *line)
{
	if (bsdtar->next_line_is_dir) {
		if (*line != '\0')
			set_chdir(bsdtar, line);
		else {
			bsdtar_warnc(bsdtar, 0,
			    "Meaningless argument for -C: ''");
			bsdtar->return_value = 1;
		}
		bsdtar->next_line_is_dir = 0;
	} else if (!bsdtar->option_null && strcmp(line, "-C") == 0)
		bsdtar->next_line_is_dir = 1;
	else {
		if (*line != '/')
			do_chdir(bsdtar); /* Handle a deferred -C */
		write_hierarchy(bsdtar, bsdtar->archive, line);
	}
	return (0);
}
Пример #10
0
static void make_file(const char* filename, int save_cwd)
{
  int fd;
  int saved_umask;
  int mode;
  char tmpname[256];
  char* ptr;
  struct timeval t;
  
  switch (do_chdir(save_cwd)) {
  case 0: return;
  case 2: mode = 0666; break;
  default: mode = 0600; break;
  }
  saved_umask = umask(0);

  gettimeofday(&t, 0);
  ptr = tmpname; *ptr++ = '.';
  ptr = utoa2(t.tv_sec, ptr); *ptr++ = '.';
  ptr = utoa2(t.tv_usec, ptr); *ptr++ = ':';
  ptr = utoa2(getpid(), ptr);
  
  if ((fd = open(tmpname, O_WRONLY|O_CREAT|O_EXCL, mode)) == -1)
    warn3sys("Could not open '", tmpname, "' for writing");
  else {
    if (!write_env(fd, "USER") ||
	!write_env(fd, "DOMAIN") ||
	close(fd) == -1) {
      warn3sys("Could not write to '", filename, "'");
      close(fd);
    }
    else if (rename(tmpname, filename) == -1)
      warn5sys("Could not rename '", tmpname, "' to '", filename, "'");
    unlink(tmpname);
  }
  if (save_cwd) {
    umask(saved_umask);
    do_chdir_back();
  }
}
Пример #11
0
int		change_dir(char *path) {
  struct stat	sb;

  if (access(path, F_OK) == 0) {
    if (stat(path, &sb) == 0) {
      if (S_ISDIR(sb.st_mode)) {
	if (access(path, X_OK) == 0) {
	  return do_chdir(path);
	}
	else
	  shell_warn("cd: %s: Permission denied.\n", path);
      }
      else
	shell_warn("cd: %s: Not a directory.\n", path);
    }
    else
      shell_warn("cd: %s: Permission denied.\n", path);
  }
  else
    shell_warn("cd: %s: No such file or directory.\n", path);
  return -1;
}
Пример #12
0
int vfs_selftest(kshell_t *kshell, int argc, char **argv)
{
  int fd1,fd2;
  char *y="/ab/fil";
  char x[2];
  int err;
  do_mkdir("/ab");
  do_mknod("/ab/new", S_IFCHR,MKDEVID(1,1));
  fd1=do_open("/ab/new",2);
  fd2=do_dup2(fd1,NFILES+1);
  if(fd2<0)
    {
      dbg(DBG_PRINT,"File not created\n");
    }
  do_mknod("/ab/notmade",4096,MKDEVID(1,1));
  do_mknod("/ab/new/not",S_IFCHR,MKDEVID(1,1));
  do_mknod("/ab/new", S_IFCHR,MKDEVID(1,1));
  do_mknod("", S_IFCHR,MKDEVID(1,1));

  /*do_close(fd1);*/
    for(fd2=1;fd2<35;fd2++)
    {
      sprintf(x,"%d",fd2);
      strcat(y,x);
      do_mknod(y,S_IFCHR,MKDEVID(1,0));
      err=do_open(y,2);
      if(err<0)
	{
	  break;
	}
      if(fd2<10)
	{
	  y[strlen(y)-1]='\0';
	}
      else
	{
	   y[strlen(y)-2]='\0';
	}
      
    }
do_mknod("/ab/new1", S_IFCHR,MKDEVID(1,1));
 err=do_dup(fd1);
  do_unlink("/ab/new/ab");
 do_unlink("/ab/new");
 do_close(fd1);
 for(fd2=NFILES-1;fd2>0;fd2--)
   {
     err=do_close(fd2);
     sprintf(x,"%d",fd2);
      strcat(y,x);
      do_unlink(y);  
      if(err<0)
	{
	  break;
	}
      if(fd2<10)
	{
	  y[strlen(y)-1]='\0';
	}
      else
	{
	   y[strlen(y)-2]='\0';
	}
   }
 do_link("/a","/dev");
 do_link("/dev","/a");
 do_link("/dev","/a");
 do_rmdir("/a");
 /* mkdir("/k");
    do_link("/ab","/k");*/
  do_rmdir("/ab");
  /*do_rmdir("/k");*/

 /*GS: SELF TESTS*/
    dbg(DBG_PRINT,"\n*************************************************************\n");
    dbg(DBG_PRINT,"\n\n\n\n(GRADING2C)(kmain.c)(selftest_proc_run) selftests begin\n");

    int retVal = 0;
    int i = 0;

    /* 1. dbg(DBG_PRINT, "(GRADING2C) (vfs_syscall.c) (do_stat)  strlen too long, return -ENAMETOOLONG\n");*/
    char longPath[1024 + 1] = {0};
    for(i = 0; i < 1025; i++)
        longPath[i] = 'a';
    struct stat buf;
    retVal = do_stat(longPath, &buf);
    retVal=do_chdir(longPath);

    /*2. dbg(DBG_PRINT, "(GRADING2B) ENOTDIR or ENOENT\n");*/
    retVal = do_stat("", &buf);

    /*3. dbg(DBG_PRINT, "(GRADING2C) (vfs_syscall.c) (do_getdent) Invalid file descriptor fd, return -EBADF\n");*/
    struct dirent dirp;
    retVal = do_getdent(-1, &dirp);

    /*4. dbg(DBG_PRINT, "(GRADING2C) (vfs_syscall.c) (do_getdent) Invalid file descriptor fd, return -EBADF\n");*/
    retVal = do_getdent(1, &dirp);

    /*5. dbg(DBG_PRINT, "(GRADING2C) (vfs_syscall.c) (do_getdent) File descriptor does not refer to a directory, return -ENOTDIR\n");*/
    do_mknod("/./file", S_IFCHR,MKDEVID(1,1));
    fd1 = do_open("/./file",2);
    retVal = do_getdent(fd1, &dirp);

    do_unlink("/./file");
    do_close(fd1);
    /*6. dbg(DBG_PRINT, "(GRADING2C) (vfs_syscall.c) (do_rename) Both are valid names \n");*/
    /* and */
    /*7. dbg(DBG_PRINT, "(GRADING2C) (vfs_syscall.c) (do_rename) error do_link, return error\n"); \n");*/
    retVal = do_rename("/./aaa", "/./bbb");


    dbg(DBG_PRINT,"\n\nretVal=%d",retVal);
    dbg(DBG_PRINT,"\n*************************************************************\n");
  return 0;
}
Пример #13
0
static uint8_t mount_line(void) {
  FRESULT res;
  UINT bytesread;
  uint8_t i,*str,*strend, *buffer_start;
  uint16_t curpos;
  bool got_colon = false;
  uint8_t olderror = current_error;
  current_error = ERROR_OK;

  /* Kill all buffers */
  free_multiple_buffers(FMB_USER_CLEAN);

  curpos = 0;
  strend = NULL;
  buffer_start = command_buffer + 1;
  globalflags |= SWAPLIST_ASCII;

  for (i=0;i<=linenum;i++) {
    str = buffer_start;

    res = f_lseek(&swaplist,curpos);
    if (res != FR_OK) {
      parse_error(res,1);
      return 0;
    }

    res = f_read(&swaplist, str, CONFIG_COMMAND_BUFFER_SIZE - 1, &bytesread);
    if (res != FR_OK) {
      parse_error(res,1);
      return 0;
    }

    /* Terminate string in buffer */
    if (bytesread < CONFIG_COMMAND_BUFFER_SIZE - 1)
      str[bytesread] = 0;

    if (bytesread == 0) {
      if (linenum == 255) {
        /* Last entry requested, found it */
        linenum = i-1;
      } else {
        /* End of file - restart loop to read the first entry */
        linenum = 0;
      }
      i = -1; /* I could've used goto instead... */
      curpos = 0;
      continue;
    }

    /* Skip name */
    got_colon = false;

    while (*str != '\r' && *str != '\n') {
      if (*str == ':')
        got_colon = true;
      str++;
    }

    strend = str;

    /* Skip line terminator */
    while (*str == '\r' || *str == '\n') str++;

    /* check for PETSCII marker */
    if (curpos == 0) {
      if (!memcmp_P(buffer_start, petscii_marker, sizeof(petscii_marker))) {
        /* swaplist is in PETSCII, ignore this line */
        globalflags &= ~SWAPLIST_ASCII;
        i--;
      }
    }

    curpos += str - buffer_start;
  }

  /* Terminate file name */
  *strend = 0;

  if (partition[swappath.part].fop != &fatops)
    image_unmount(swappath.part);

  /* Start in the partition+directory of the swap list */
  current_part = swappath.part;
  display_current_part(current_part);
  partition[current_part].current_dir = swappath.dir;

  /* add a colon if neccessary */
  if (!got_colon && buffer_start[0] != '/') {
    command_buffer[0] = ':';
    buffer_start = command_buffer;
  }

  /* recode entry if neccessary */
  if (globalflags & SWAPLIST_ASCII)
    asc2pet(buffer_start);

  /* parse and change */
  do_chdir(buffer_start);

  if (current_error != 0 && current_error != ERROR_DOSVERSION) {
    current_error = olderror;
    return 0;
  }

  return 1;
}
Пример #14
0
int main(int argc, char *argv[])
{
	int ret, i, action = -1;
	char config_file[PATH_MAX] = {};
	int type = 0;
	struct utsname u;
	int version, major, minor;

	/* Check kernel version: it must be >= 2.6.18 */
	if (uname(&u) == -1) {
		fprintf(stderr, "Can't retrieve kernel version via uname()\n");
		exit(EXIT_FAILURE);
	}
	sscanf(u.release, "%d.%d.%d", &version, &major, &minor);
	if (version < 2 && major < 6 && minor < 18) {
		fprintf(stderr, "Linux kernel version must be >= 2.6.18\n");
		exit(EXIT_FAILURE);
	}

	for (i=1; i<argc; i++) {
		switch(argv[i][1]) {
		case 'd':
			set_operation_mode(&type, DAEMON, argv);
			break;
		case 'c':
			set_operation_mode(&type, REQUEST, argv);
			i = set_action_by_table(i, argc, argv,
						CT_COMMIT, EXP_COMMIT,
						ALL_COMMIT, &action);
			break;
		case 'i':
			set_operation_mode(&type, REQUEST, argv);
			i = set_action_by_table(i, argc, argv,
						CT_DUMP_INTERNAL,
						EXP_DUMP_INTERNAL,
						CT_DUMP_INTERNAL, &action);
			break;
		case 'e':
			set_operation_mode(&type, REQUEST, argv);
			i = set_action_by_table(i, argc, argv,
						CT_DUMP_EXTERNAL,
						EXP_DUMP_EXTERNAL,
						CT_DUMP_EXTERNAL, &action);
			break;
		case 'C':
			if (++i < argc) {
				strncpy(config_file, argv[i], PATH_MAX);
				if (strlen(argv[i]) >= PATH_MAX){
					config_file[PATH_MAX-1]='\0';
					fprintf(stderr, "Path to config file "
						        "to long. Cutting it "
							"down to %d characters",
							PATH_MAX);
				}
				break;
			}
			show_usage(argv[0]);
			fprintf(stderr, "Missing config filename\n");
			break;
		case 'F':
			set_operation_mode(&type, REQUEST, argv);
			i = set_action_by_table(i, argc, argv,
						CT_FLUSH_MASTER,
						EXP_FLUSH_MASTER,
						ALL_FLUSH_MASTER, &action);
			break;
		case 'f':
			set_operation_mode(&type, REQUEST, argv);
			if (i+1 < argc && argv[i+1][0] != '-') {
				if (strncmp(argv[i+1], "internal",
					    strlen(argv[i+1])) == 0) {
					action = CT_FLUSH_INT_CACHE;
					i++;
				} else if (strncmp(argv[i+1], "external",
						 strlen(argv[i+1])) == 0) {
					action = CT_FLUSH_EXT_CACHE;
					i++;
				} else {
					fprintf(stderr, "ERROR: unknown "
							"parameter `%s' for "
							"option `-f'\n",
							argv[i+1]);
					exit(EXIT_FAILURE);
				}
			} else {
				/* default to general flushing */
				action = ALL_FLUSH_CACHE;
			}
			break;
		case 'R':
			set_operation_mode(&type, REQUEST, argv);
			i = set_action_by_table(i, argc, argv,
						CT_RESYNC_MASTER,
						EXP_RESYNC_MASTER,
						ALL_RESYNC_MASTER, &action);
			break;
		case 'B':
			set_operation_mode(&type, REQUEST, argv);
			action = SEND_BULK;
			break;
		case 'S':
			set_operation_mode(&type, REQUEST, argv);
			action = SEND_BULKEXP;
			break;
		case 't':
			set_operation_mode(&type, REQUEST, argv);
			action = RESET_TIMERS;
			break;
		case 'k':
			set_operation_mode(&type, REQUEST, argv);
			action = KILL;
			break;
		case 's':
			set_operation_mode(&type, REQUEST, argv);
			/* we've got a parameter */
			if (i+1 < argc && argv[i+1][0] != '-') {
				if (strncmp(argv[i+1], "network",
					    strlen(argv[i+1])) == 0) {
					action = STATS_NETWORK;
					i++;
				} else if (strncmp(argv[i+1], "cache",
						 strlen(argv[i+1])) == 0) {
					action = STATS_CACHE;
					i++;
				} else if (strncmp(argv[i+1], "runtime",
						 strlen(argv[i+1])) == 0) {
					action = STATS_RUNTIME;
					i++;
				} else if (strncmp(argv[i+1], "multicast",
						 strlen(argv[i+1])) == 0) {
					fprintf(stderr, "WARNING: use `link' "
						"instead of `multicast' as "
						"parameter.\n");
					action = STATS_LINK;
					i++;
				} else if (strncmp(argv[i+1], "link",
						 strlen(argv[i+1])) == 0) {
					action = STATS_LINK;
					i++;
				} else if (strncmp(argv[i+1], "rsqueue",
						strlen(argv[i+1])) == 0) {
					action = STATS_RSQUEUE;
					i++;
				} else if (strncmp(argv[i+1], "process",
						 strlen(argv[i+1])) == 0) {
					action = STATS_PROCESS;
					i++;
				} else if (strncmp(argv[i+1], "queue",
						strlen(argv[i+1])) == 0) {
					action = STATS_QUEUE;
					i++;
				} else if (strncmp(argv[i+1], "ct",
						strlen(argv[i+1])) == 0) {
					action = STATS;
					i++;
				} else if (strncmp(argv[i+1], "expect",
						strlen(argv[i+1])) == 0) {
					action = EXP_STATS;
					i++;
				} else {
					fprintf(stderr, "ERROR: unknown "
							"parameter `%s' for "
							"option `-s'\n",
							argv[i+1]);
					exit(EXIT_FAILURE);
				}
			} else {
				/* default to general statistics */
				action = STATS;
			}
			break;
		case 'n':
			set_operation_mode(&type, REQUEST, argv);
			action = REQUEST_DUMP;
			break;
		case 'x':
			if (action == CT_DUMP_INTERNAL)
				action = CT_DUMP_INT_XML;
			else if (action == CT_DUMP_EXTERNAL)
				action = CT_DUMP_EXT_XML;
			else if (action == EXP_DUMP_INTERNAL)
				action = EXP_DUMP_INT_XML;
			else if (action == EXP_DUMP_EXTERNAL)
				action = EXP_DUMP_EXT_XML;
			else {
				show_usage(argv[0]);
				fprintf(stderr, "Error: Invalid parameters\n");
				exit(EXIT_FAILURE);

			}
			break;
		case 'v':
			show_version();
			exit(EXIT_SUCCESS);
		case 'h':
			show_usage(argv[0]);
			exit(EXIT_SUCCESS);
		default:
			show_usage(argv[0]);
			fprintf(stderr, "Unknown option: %s\n", argv[i]);
			return 0;
			break;
		}
	}

	if (!config_file[0])
		strcpy(config_file, DEFAULT_CONFIGFILE);

	umask(0177);

	if ((ret = init_config(config_file)) == -1) {
		fprintf(stderr, "can't open config file `%s'\n", config_file);
		exit(EXIT_FAILURE);
	}

	if (type == REQUEST) {
		if (do_local_request(action, &conf.local, local_step) == -1) {
			fprintf(stderr, "can't connect: is conntrackd "
					"running? appropriate permissions?\n");
			exit(EXIT_FAILURE);
		}
		exit(EXIT_SUCCESS);
	}

	/*
	 * Setting up logging
	 */
	if (init_log() == -1)
		exit(EXIT_FAILURE);

	/*
	 * lock file
	 */
	/*ret = open(CONFIG(lockfile), O_CREAT | O_EXCL | O_TRUNC, 0600);
	if (ret == -1) {
		fprintf(stderr, "lockfile `%s' exists, perhaps conntrackd "
			        "already running?\n", CONFIG(lockfile));
		exit(EXIT_FAILURE);
	}
	close(ret);*/

	/*
	 * Setting process priority and scheduler
	 */
	set_nice_value(CONFIG(nice));

	if (CONFIG(sched).type != SCHED_OTHER) {
		struct sched_param schedparam = {
			.sched_priority = CONFIG(sched).prio,
		};

		ret = sched_setscheduler(0, CONFIG(sched).type, &schedparam);
		if (ret == -1) {
			perror("sched");
			exit(EXIT_FAILURE);
		}
	}

	/*
	 * initialization process
	 */

	if (init() == -1) {
		close_log();
		fprintf(stderr, "ERROR: conntrackd cannot start, please "
				"check the logfile for more info\n");
		unlink(CONFIG(lockfile));
		exit(EXIT_FAILURE);
	}

	do_chdir("/");
	close(STDIN_FILENO);

	sd_ct_watchdog_init();

	/* Daemonize conntrackd */
	if (type == DAEMON) {
		pid_t pid;

		if ((pid = fork()) == -1) {
			perror("fork has failed: ");
			exit(EXIT_FAILURE);
		} else if (pid) {
			sd_ct_mainpid(pid);
			exit(EXIT_SUCCESS);
		}

		setsid();

		close(STDOUT_FILENO);
		close(STDERR_FILENO);

		dlog(LOG_NOTICE, "-- starting in daemon mode --");
	} else
		dlog(LOG_NOTICE, "-- starting in console mode --");

	sd_ct_init();

	/*
	 * run main process
	 */
	select_main_loop();
	return 0;
}
Пример #15
0
void *extra_self_tests(int arg1, void *arg2)
{
        /* creating /test1/test2/ directories */
   dbg(DBG_ERROR | DBG_VFS,"TEST: Creating directories\n");        
                do_mkdir("dir");
                do_mkdir("dir/dir1");
                do_mkdir("dir/dir2");
                do_mkdir("dir/dir3");             
                do_mkdir("dir/dir4");  
   dbg(DBG_ERROR | DBG_VFS,"TEST: Directories are created\n");
        int fd;
        char *file2buf="File 2 write only test case";
        char *file1buf="Testing file_1 for write operation";
        char readbuf[150];

   dbg(DBG_ERROR | DBG_VFS,"TEST: Change directory to dir/dir1\n");
        do_chdir("dir/dir1");

        /* file1.txt creation with O_CREAT|O_WRONLY  flag*/
   dbg(DBG_ERROR | DBG_VFS,"TEST: Create file1.txt with O_CREAT|O_WRONLY flag in directory dir/dir1\n");
        fd = do_open("file1.txt", O_CREAT|O_WRONLY);
        do_write(fd, file1buf, strlen(file1buf));
        do_close(fd);
        
        /* file2.txt creation with O_CREAT|O_RDONLY  flag*/
   dbg(DBG_ERROR | DBG_VFS,"TEST: Change directory to dir/dir2\n");
        do_chdir("/dir/dir2");
        
   dbg(DBG_ERROR | DBG_VFS,"TEST: Create file2.txt with O_CREAT | O_RDONLY flag  in directory dir/dir2\n");
        fd = do_open("file2.txt", O_CREAT | O_RDONLY);
        do_close(fd);
        
         /* Write into file2.txt using O_WRONLY flag*/
   dbg(DBG_ERROR | DBG_VFS,"TEST: Write into file2.txt with O_WRONLY flag in directory dir/dir2\n");  
        fd = do_open("file2.txt", O_WRONLY);
        do_write(fd, file2buf, strlen(file2buf));
        do_close(fd);
   dbg(DBG_ERROR | DBG_VFS,"TEST: written chars: \"%s\" in file2.txt\n",file2buf);
   
        char *appendbuf=" Appending for O_WRONLY|O_APPEND mode";
      /* Append into file2.txt using  O_WRONLY|O_APPEND  flag*/
   dbg(DBG_ERROR | DBG_VFS,"TEST: Append into file2.txt with O_WRONLY|O_APPEND flag in directory dir/dir2\n");  
        fd = do_open("file2.txt", O_WRONLY|O_APPEND);
        do_write(fd, appendbuf, strlen(appendbuf));
        do_close(fd);
   dbg(DBG_ERROR | DBG_VFS,"TEST: Appending chars: \"%s\" in file2.txt\n",appendbuf);
        fd = do_open("file2.txt", O_RDONLY);
        memset(readbuf,0,sizeof(char)*150);
        do_read(fd,readbuf,strlen(file2buf)+strlen(appendbuf));
   dbg(DBG_ERROR | DBG_VFS,"TEST: After Appending text in file2.txt is: \"%s\" \n",readbuf);

        char *append2buf=" Appending for O_RDWR|O_APPEND mode in file2";
      /* Append into file2.txt using  O_RDWR|O_APPEND  flag*/
   dbg(DBG_ERROR | DBG_VFS,"TEST: Append into file2.txt with O_RDWR|O_APPEND flag in directory dir/dir2\n");  
        fd = do_open("file2.txt", O_RDWR|O_APPEND);
        do_write(fd, append2buf, strlen(append2buf));
        do_close(fd);
   dbg(DBG_ERROR | DBG_VFS,"TEST: Appending chars: \"%s\" in file2.txt\n",append2buf);
        fd = do_open("file2.txt", O_RDONLY);
        memset(readbuf,0,sizeof(char)*150);
        do_read(fd,readbuf,strlen(file2buf)+strlen(append2buf)+strlen(appendbuf));
   dbg(DBG_ERROR | DBG_VFS,"TEST: After Appending text in file2.txt is: \"%s\" \n",readbuf);

   dbg(DBG_ERROR | DBG_VFS,"TEST:Linking Source directory => /dir/dir2, Destination directory => /dir/linkofdir2 \n");
        do_chdir("/");
        do_link("dir/dir2","dir/linkofdir2");

   dbg(DBG_ERROR | DBG_VFS,"TEST:Linking Source file => /dir/dir1/file1.txt, to the Destination => /dir/linkoffile1 \n");
        do_link("dir/dir1/file1.txt","dir/linkoffile1");
        
   dbg(DBG_ERROR | DBG_VFS,"TEST: Renaming directory from dir/dir3 to dir/renamed \n");
        do_rename("dir/dir3","dir/renameddir3");

   dbg(DBG_ERROR | DBG_VFS,"TEST: Renaming file from dir/dir1/file1.txt to dir/dir1/renamedfile1.txt \n");
        do_rename("dir/dir1/file1.txt","dir/dir1/renamedfile1.txt");

   dbg(DBG_ERROR | DBG_VFS,"TEST: Removing directory dir/dir4 \n");
        do_rmdir("dir/dir4");

   dbg(DBG_ERROR | DBG_VFS,"TEST: reading 18 chars from file: /dir/linkoffile2 which is hard link of /dir/dir2/file2.txt \n");
        fd = do_open("dir/linkoffile2", O_RDONLY);
        memset(readbuf,0,sizeof(char)*150);
        do_close(fd);
   dbg(DBG_ERROR | DBG_VFS,"TEST: read 18 chars: \"%s\" from file: /dir/linkoffile1\n",readbuf);
   
   dbg(DBG_ERROR | DBG_VFS,"TEST: reading file using lseek function on  /dir/linkoffile2 which is hard link of /dir/dir2/file2.txt \n");
        memset(readbuf,0,sizeof(char)*150);
        fd = do_open("dir/linkoffile2", O_RDONLY);
        do_lseek(fd,-19,2);
        do_read(fd,readbuf,19);
        do_close(fd);
   dbg(DBG_ERROR | DBG_VFS,"TEST: read chars: \"%s\" using lseek from file: /dir/linkoffile1\n",readbuf);
   
   dbg(DBG_ERROR | DBG_VFS,"TEST: creating a duplicate file descriptor of file: /dir/dir2/file2.txt using do_dup()\n");
        fd = do_open("/dir/dir2/file2.txt", O_RDONLY);
    int fd2= do_dup(fd);
   dbg(DBG_ERROR | DBG_VFS,"TEST: duplicate file descriptor is :\"%d\" of file: /dir/dir2/file2.txt \n",fd2);
             do_close(fd);        do_close(fd2);
                     
   dbg(DBG_ERROR | DBG_VFS,"TEST: creating a duplicate file descriptor of file: /dir/dir2/file2.txt using do_dup2()\n");    
        fd = do_open("/dir/dir2/file2.txt", O_RDONLY);
        fd2= do_dup2(fd,20);
   dbg(DBG_ERROR | DBG_VFS,"TEST: custom file descriptor is :\"%d\" of file: /dir/dir2/file2.txt \n",fd2);
                do_close(fd);        do_close(fd2);

        /*  Testing stat
        struct *statbuf;
   dbg(DBG_ERROR | DBG_VFS,"TEST: Testing the stat system call for directory dir\n");
        do_stat("dir",statbuf);
   dbg(DBG_ERROR | DBG_VFS,"TEST: Output of stat for directory dir is :\"%s\" \n",statbuf);*/

        shellTest(); 

     return NULL;
}
Пример #16
0
/*
 * Write user-specified files/dirs to opened archive.
 */
static void
write_archive(struct archive *a, struct bsdtar *bsdtar)
{
	struct sigaction sa;
	const char *arg;
	struct archive_entry *entry, *sparse_entry;

	/* We want to catch SIGINFO and SIGUSR1. */
	siginfo_init(bsdtar);

	/* We also want to catch SIGQUIT and ^Q. */
	if (sigquit_init())
		exit(1);

	/* And SIGUSR2, too. */
	sa.sa_handler = sigusr2_handler;
	sigemptyset(&sa.sa_mask);
	sa.sa_flags = 0;
	if (sigaction(SIGUSR2, &sa, NULL))
		bsdtar_errc(bsdtar, 1, 0, "cannot install signal handler");

	/* Allocate a buffer for file data. */
	if ((bsdtar->buff = malloc(FILEDATABUFLEN)) == NULL)
		bsdtar_errc(bsdtar, 1, 0, "cannot allocate memory");

	if ((bsdtar->resolver = archive_entry_linkresolver_new()) == NULL)
		bsdtar_errc(bsdtar, 1, 0, "cannot create link resolver");
	archive_entry_linkresolver_set_strategy(bsdtar->resolver,
	    archive_format(a));
	if ((bsdtar->diskreader = archive_read_disk_new()) == NULL)
		bsdtar_errc(bsdtar, 1, 0, "Cannot create read_disk object");
	archive_read_disk_set_standard_lookup(bsdtar->diskreader);

	if (bsdtar->names_from_file != NULL)
		archive_names_from_file(bsdtar, a);

	while (*bsdtar->argv) {
		if (truncate_archive(bsdtar))
			break;
		if (checkpoint_archive(bsdtar, 0))
			exit(1);

		arg = *bsdtar->argv;
		if (arg[0] == '-' && arg[1] == 'C') {
			arg += 2;
			if (*arg == '\0') {
				bsdtar->argv++;
				arg = *bsdtar->argv;
				if (arg == NULL) {
					bsdtar_warnc(bsdtar, 0,
					    "Missing argument for -C");
					bsdtar->return_value = 1;
					goto cleanup;
				}
				if (*arg == '\0') {
					bsdtar_warnc(bsdtar, 0,
					    "Meaningless argument for -C: ''");
					bsdtar->return_value = 1;
					goto cleanup;
				}
			}
			set_chdir(bsdtar, arg);
		} else {
			if (arg[0] != '/' &&
			    (arg[0] != '@' || arg[1] != '/') &&
			    (arg[0] != '@' || arg[1] != '@'))
				do_chdir(bsdtar); /* Handle a deferred -C */
			if (arg[0] == '@' && arg[1] == '@') {
				if (append_archive_tarsnap(bsdtar, a,
				    arg + 2) != 0)
					break;
			} else if (arg[0] == '@') {
				if (append_archive_filename(bsdtar, a,
				    arg + 1) != 0)
					break;
			} else
#if defined(_WIN32) && !defined(__CYGWIN__)
				write_hierarchy_win(bsdtar, a, arg,
				    write_hierarchy);
#else
				write_hierarchy(bsdtar, a, arg);
#endif
		}
		bsdtar->argv++;
	}

	/*
	 * This code belongs to bsdtar and is used when writing archives in
	 * "new cpio" format.  It has no effect in tarsnap, since tarsnap
	 * doesn't write archives in this format; but I'm leaving it in to
	 * make the diffs smaller.
	 */
	entry = NULL;
	archive_entry_linkify(bsdtar->resolver, &entry, &sparse_entry);
	while (entry != NULL) {
		write_entry_backend(bsdtar, a, entry, NULL, NULL);
		archive_entry_free(entry);
		entry = NULL;
		archive_entry_linkify(bsdtar->resolver, &entry, &sparse_entry);
	}

	if (archive_write_close(a)) {
		bsdtar_warnc(bsdtar, 0, "%s", archive_error_string(a));
		bsdtar->return_value = 1;
	}

cleanup:
	/* Free file data buffer. */
	free(bsdtar->buff);
	archive_entry_linkresolver_free(bsdtar->resolver);
	bsdtar->resolver = NULL;
	archive_read_finish(bsdtar->diskreader);
	bsdtar->diskreader = NULL;

	if (bsdtar->option_totals && (bsdtar->return_value == 0)) {
		fprintf(stderr, "Total bytes written: " BSDTAR_FILESIZE_PRINTF "\n",
		    (BSDTAR_FILESIZE_TYPE)archive_position_compressed(a));
	}

	archive_write_finish(a);

	/* Restore old SIGINFO + SIGUSR1 handlers. */
	siginfo_done(bsdtar);
}
Пример #17
0
/*
 * Write user-specified files/dirs to opened archive.
 */
static void
write_archive(struct archive *a, struct bsdtar *bsdtar)
{
	const char *arg;
	struct archive_entry *entry, *sparse_entry;

	/* Choose a suitable copy buffer size */
	bsdtar->buff_size = 64 * 1024;
	while (bsdtar->buff_size < (size_t)bsdtar->bytes_per_block)
	  bsdtar->buff_size *= 2;
	/* Try to compensate for space we'll lose to alignment. */
	bsdtar->buff_size += 16 * 1024;

	/* Allocate a buffer for file data. */
	if ((bsdtar->buff = malloc(bsdtar->buff_size)) == NULL)
		lafe_errc(1, 0, "cannot allocate memory");

	if ((bsdtar->resolver = archive_entry_linkresolver_new()) == NULL)
		lafe_errc(1, 0, "cannot create link resolver");
	archive_entry_linkresolver_set_strategy(bsdtar->resolver,
	    archive_format(a));

	/* Create a read_disk object. */
	if ((bsdtar->diskreader = archive_read_disk_new()) == NULL)
		lafe_errc(1, 0, "Cannot create read_disk object");
	/* Tell the read_disk how handle symlink. */
	switch (bsdtar->symlink_mode) {
	case 'H':
		archive_read_disk_set_symlink_hybrid(bsdtar->diskreader);
		break;
	case 'L':
		archive_read_disk_set_symlink_logical(bsdtar->diskreader);
		break;
	default:
		archive_read_disk_set_symlink_physical(bsdtar->diskreader);
		break;
	}
	/* Register entry filters. */
	archive_read_disk_set_matching(bsdtar->diskreader,
	    bsdtar->matching, excluded_callback, bsdtar);
	archive_read_disk_set_metadata_filter_callback(
	    bsdtar->diskreader, metadata_filter, bsdtar);
	/* Set the behavior of archive_read_disk. */
	archive_read_disk_set_behavior(bsdtar->diskreader,
	    bsdtar->readdisk_flags);
	archive_read_disk_set_standard_lookup(bsdtar->diskreader);

	if (bsdtar->names_from_file != NULL)
		archive_names_from_file(bsdtar, a);

	while (*bsdtar->argv) {
		arg = *bsdtar->argv;
		if (arg[0] == '-' && arg[1] == 'C') {
			arg += 2;
			if (*arg == '\0') {
				bsdtar->argv++;
				arg = *bsdtar->argv;
				if (arg == NULL) {
					lafe_warnc(0, "%s",
					    "Missing argument for -C");
					bsdtar->return_value = 1;
					goto cleanup;
				}
				if (*arg == '\0') {
					lafe_warnc(0,
					    "Meaningless argument for -C: ''");
					bsdtar->return_value = 1;
					goto cleanup;
				}
			}
			set_chdir(bsdtar, arg);
		} else {
			if (*arg != '/' && (arg[0] != '@' || arg[1] != '/'))
				do_chdir(bsdtar); /* Handle a deferred -C */
			if (*arg == '@') {
				if (append_archive_filename(bsdtar, a,
				    arg + 1) != 0)
					break;
			} else
				write_hierarchy(bsdtar, a, arg);
		}
		bsdtar->argv++;
	}

	archive_read_disk_set_matching(bsdtar->diskreader, NULL, NULL, NULL);
	archive_read_disk_set_metadata_filter_callback(
	    bsdtar->diskreader, NULL, NULL);
	entry = NULL;
	archive_entry_linkify(bsdtar->resolver, &entry, &sparse_entry);
	while (entry != NULL) {
		int r;
		struct archive_entry *entry2;
		struct archive *disk = bsdtar->diskreader;

		/*
		 * This tricky code here is to correctly read the cotents
		 * of the entry because the disk reader bsdtar->diskreader
		 * is pointing at does not have any information about the
		 * entry by this time and using archive_read_data_block()
		 * with the disk reader consequently must fail. And we
		 * have to re-open the entry to read the contents.
		 */
		/* TODO: Work with -C option as well. */
		r = archive_read_disk_open(disk,
			archive_entry_sourcepath(entry));
		if (r != ARCHIVE_OK) {
			lafe_warnc(archive_errno(disk),
			    "%s", archive_error_string(disk));
			bsdtar->return_value = 1;
			archive_entry_free(entry);
			continue;
		}

		/*
		 * Invoke archive_read_next_header2() to work
		 * archive_read_data_block(), which is called via write_file(),
		 * without failure.
		 */
		entry2 = archive_entry_new();
		r = archive_read_next_header2(disk, entry2);
		archive_entry_free(entry2);
		if (r != ARCHIVE_OK) {
			lafe_warnc(archive_errno(disk),
			    "%s", archive_error_string(disk));
			if (r == ARCHIVE_FATAL)
				bsdtar->return_value = 1;
			else
				archive_read_close(disk);
			archive_entry_free(entry);
			continue;
		}

		write_file(bsdtar, a, entry);
		archive_entry_free(entry);
		archive_read_close(disk);
		entry = NULL;
		archive_entry_linkify(bsdtar->resolver, &entry, &sparse_entry);
	}

	if (archive_write_close(a)) {
		lafe_warnc(0, "%s", archive_error_string(a));
		bsdtar->return_value = 1;
	}

cleanup:
	/* Free file data buffer. */
	free(bsdtar->buff);
	archive_entry_linkresolver_free(bsdtar->resolver);
	bsdtar->resolver = NULL;
	archive_read_free(bsdtar->diskreader);
	bsdtar->diskreader = NULL;

	if (bsdtar->option_totals) {
		fprintf(stderr, "Total bytes written: %s\n",
		    tar_i64toa(archive_filter_bytes(a, -1)));
	}

	archive_write_free(a);
}
Пример #18
0
/*
 * Handle 'x' and 't' modes.
 */
static void
read_archive(struct bsdtar *bsdtar, char mode)
{
	FILE			 *out;
	struct archive		 *a;
	struct archive_entry	 *entry;
	const struct stat	 *st;
	int			  r;

	while (*bsdtar->argv) {
		include(bsdtar, *bsdtar->argv);
		bsdtar->argv++;
	}

	if (bsdtar->names_from_file != NULL)
		include_from_file(bsdtar, bsdtar->names_from_file);

	a = archive_read_new();
	if (bsdtar->compress_program != NULL)
		archive_read_support_compression_program(a, bsdtar->compress_program);
	else
		archive_read_support_compression_all(a);
	archive_read_support_format_all(a);
	if (archive_read_open_file(a, bsdtar->filename,
	    bsdtar->bytes_per_block != 0 ? bsdtar->bytes_per_block :
	    DEFAULT_BYTES_PER_BLOCK))
		bsdtar_errc(bsdtar, 1, 0, "Error opening archive: %s",
		    archive_error_string(a));

	do_chdir(bsdtar);
	for (;;) {
		/* Support --fast-read option */
		if (bsdtar->option_fast_read &&
		    unmatched_inclusions(bsdtar) == 0)
			break;

		r = archive_read_next_header(a, &entry);
		if (r == ARCHIVE_EOF)
			break;
		if (r < ARCHIVE_OK)
			bsdtar_warnc(bsdtar, 0, "%s", archive_error_string(a));
		if (r <= ARCHIVE_WARN)
			bsdtar->return_value = 1;
		if (r == ARCHIVE_RETRY) {
			/* Retryable error: try again */
			bsdtar_warnc(bsdtar, 0, "Retrying...");
			continue;
		}
		if (r == ARCHIVE_FATAL)
			break;

		/*
		 * Exclude entries that are too old.
		 */
		st = archive_entry_stat(entry);
		if (bsdtar->newer_ctime_sec > 0) {
			if (st->st_ctime < bsdtar->newer_ctime_sec)
				continue; /* Too old, skip it. */
			if (st->st_ctime == bsdtar->newer_ctime_sec
			    && ARCHIVE_STAT_CTIME_NANOS(st)
			    <= bsdtar->newer_ctime_nsec)
				continue; /* Too old, skip it. */
		}
		if (bsdtar->newer_mtime_sec > 0) {
			if (st->st_mtime < bsdtar->newer_mtime_sec)
				continue; /* Too old, skip it. */
			if (st->st_mtime == bsdtar->newer_mtime_sec
			    && ARCHIVE_STAT_MTIME_NANOS(st)
			    <= bsdtar->newer_mtime_nsec)
				continue; /* Too old, skip it. */
		}

		/*
		 * Note that pattern exclusions are checked before
		 * pathname rewrites are handled.  This gives more
		 * control over exclusions, since rewrites always lose
		 * information.  (For example, consider a rewrite
		 * s/foo[0-9]/foo/.  If we check exclusions after the
		 * rewrite, there would be no way to exclude foo1/bar
		 * while allowing foo2/bar.)
		 */
		if (excluded(bsdtar, archive_entry_pathname(entry)))
			continue; /* Excluded by a pattern test. */

		/*
		 * Modify the pathname as requested by the user.  We
		 * do this for -t as well to give users a way to
		 * preview the effects of their rewrites.  We also do
		 * this before extraction security checks (including
		 * leading '/' removal).  Note that some rewrite
		 * failures prevent extraction.
		 */
		if (edit_pathname(bsdtar, entry))
			continue; /* Excluded by a rewrite failure. */

		if (mode == 't') {
			/* Perversely, gtar uses -O to mean "send to stderr"
			 * when used with -t. */
			out = bsdtar->option_stdout ? stderr : stdout;

			if (bsdtar->verbose < 2)
				safe_fprintf(out, "%s",
				    archive_entry_pathname(entry));
			else
				list_item_verbose(bsdtar, out, entry);
			fflush(out);
			r = archive_read_data_skip(a);
			if (r == ARCHIVE_WARN) {
				fprintf(out, "\n");
				bsdtar_warnc(bsdtar, 0, "%s",
				    archive_error_string(a));
			}
			if (r == ARCHIVE_RETRY) {
				fprintf(out, "\n");
				bsdtar_warnc(bsdtar, 0, "%s",
				    archive_error_string(a));
			}
			if (r == ARCHIVE_FATAL) {
				fprintf(out, "\n");
				bsdtar_warnc(bsdtar, 0, "%s",
				    archive_error_string(a));
				bsdtar->return_value = 1;
				break;
			}
			fprintf(out, "\n");
		} else {
			if (bsdtar->option_interactive &&
			    !yes("extract '%s'", archive_entry_pathname(entry)))
				continue;

			/*
			 * Format here is from SUSv2, including the
			 * deferred '\n'.
			 */
			if (bsdtar->verbose) {
				safe_fprintf(stderr, "x %s",
				    archive_entry_pathname(entry));
				fflush(stderr);
			}
			if (bsdtar->option_stdout)
				r = archive_read_data_into_fd(a, 1);
			else
				r = archive_read_extract(a, entry,
				    bsdtar->extract_flags);
			if (r != ARCHIVE_OK) {
				if (!bsdtar->verbose)
					safe_fprintf(stderr, "%s",
					    archive_entry_pathname(entry));
				safe_fprintf(stderr, ": %s",
				    archive_error_string(a));
				if (!bsdtar->verbose)
					fprintf(stderr, "\n");
				bsdtar->return_value = 1;
			}
			if (bsdtar->verbose)
				fprintf(stderr, "\n");
			if (r == ARCHIVE_FATAL)
				break;
		}
	}

	if (bsdtar->verbose > 2)
		fprintf(stdout, "Archive Format: %s,  Compression: %s\n",
		    archive_format_name(a), archive_compression_name(a));

	archive_read_finish(a);
}
Пример #19
0
/*
 * Handle 'x' and 't' modes.
 */
static void
read_archive(struct bsdtar *bsdtar, char mode, struct archive *writer)
{
	struct progress_data	progress_data;
	FILE			 *out;
	struct archive		 *a;
	struct archive_entry	 *entry;
	const char		 *reader_options;
	int			  r;

	while (*bsdtar->argv) {
		if (archive_match_include_pattern(bsdtar->matching,
		    *bsdtar->argv) != ARCHIVE_OK)
			lafe_errc(1, 0, "Error inclusion pattern: %s",
			    archive_error_string(bsdtar->matching));
		bsdtar->argv++;
	}

	if (bsdtar->names_from_file != NULL)
		if (archive_match_include_pattern_from_file(
		    bsdtar->matching, bsdtar->names_from_file,
		    bsdtar->option_null) != ARCHIVE_OK)
			lafe_errc(1, 0, "Error inclusion pattern: %s",
			    archive_error_string(bsdtar->matching));

	a = archive_read_new();
	if (cset_read_support_filter_program(bsdtar->cset, a) == 0)
		archive_read_support_filter_all(a);
	archive_read_support_format_all(a);

	reader_options = getenv(ENV_READER_OPTIONS);
	if (reader_options != NULL) {
		char *p;
		/* Set default read options. */
		p = malloc(sizeof(IGNORE_WRONG_MODULE_NAME)
		    + strlen(reader_options) + 1);
		if (p == NULL)
			lafe_errc(1, errno, "Out of memory");
		/* Prepend magic code to ignore options for
		 * a format or  modules which are not added to
		 *  the archive read object. */
		strncpy(p, IGNORE_WRONG_MODULE_NAME,
		    sizeof(IGNORE_WRONG_MODULE_NAME) -1);
		strcpy(p + sizeof(IGNORE_WRONG_MODULE_NAME) -1, reader_options);
		r = archive_read_set_options(a, p);
		free(p);
		if (r == ARCHIVE_FATAL)
			lafe_errc(1, 0, "%s", archive_error_string(a));
		else
			archive_clear_error(a);
	}
	if (ARCHIVE_OK != archive_read_set_options(a, bsdtar->option_options))
		lafe_errc(1, 0, "%s", archive_error_string(a));
	if (archive_read_open_filename(a, bsdtar->filename,
					bsdtar->bytes_per_block))
		lafe_errc(1, 0, "Error opening archive: %s",
		    archive_error_string(a));

	do_chdir(bsdtar);

	if (mode == 'x') {
		/* Set an extract callback so that we can handle SIGINFO. */
		progress_data.bsdtar = bsdtar;
		progress_data.archive = a;
		archive_read_extract_set_progress_callback(a, progress_func,
		    &progress_data);
	}

	if (mode == 'x' && bsdtar->option_chroot) {
#if HAVE_CHROOT
		if (chroot(".") != 0)
			lafe_errc(1, errno, "Can't chroot to \".\"");
#else
		lafe_errc(1, 0,
		    "chroot isn't supported on this platform");
#endif
	}

	for (;;) {
		/* Support --fast-read option */
		if (bsdtar->option_fast_read &&
		    archive_match_path_unmatched_inclusions(bsdtar->matching) == 0)
			break;

		r = archive_read_next_header(a, &entry);
		progress_data.entry = entry;
		if (r == ARCHIVE_EOF)
			break;
		if (r < ARCHIVE_OK)
			lafe_warnc(0, "%s", archive_error_string(a));
		if (r <= ARCHIVE_WARN)
			bsdtar->return_value = 1;
		if (r == ARCHIVE_RETRY) {
			/* Retryable error: try again */
			lafe_warnc(0, "Retrying...");
			continue;
		}
		if (r == ARCHIVE_FATAL)
			break;

		if (bsdtar->uid >= 0) {
			archive_entry_set_uid(entry, bsdtar->uid);
			archive_entry_set_uname(entry, NULL);
		}
		if (bsdtar->gid >= 0) {
			archive_entry_set_gid(entry, bsdtar->gid);
			archive_entry_set_gname(entry, NULL);
		}
		if (bsdtar->uname)
			archive_entry_set_uname(entry, bsdtar->uname);
		if (bsdtar->gname)
			archive_entry_set_gname(entry, bsdtar->gname);

		/*
		 * Note that pattern exclusions are checked before
		 * pathname rewrites are handled.  This gives more
		 * control over exclusions, since rewrites always lose
		 * information.  (For example, consider a rewrite
		 * s/foo[0-9]/foo/.  If we check exclusions after the
		 * rewrite, there would be no way to exclude foo1/bar
		 * while allowing foo2/bar.)
		 */
		if (archive_match_excluded(bsdtar->matching, entry))
			continue; /* Excluded by a pattern test. */

		if (mode == 't') {
			/* Perversely, gtar uses -O to mean "send to stderr"
			 * when used with -t. */
			out = bsdtar->option_stdout ? stderr : stdout;

			/*
			 * TODO: Provide some reasonable way to
			 * preview rewrites.  gtar always displays
			 * the unedited path in -t output, which means
			 * you cannot easily preview rewrites.
			 */
			if (bsdtar->verbose < 2)
				safe_fprintf(out, "%s",
				    archive_entry_pathname(entry));
			else
				list_item_verbose(bsdtar, out, entry);
			fflush(out);
			r = archive_read_data_skip(a);
			if (r == ARCHIVE_WARN) {
				fprintf(out, "\n");
				lafe_warnc(0, "%s",
				    archive_error_string(a));
			}
			if (r == ARCHIVE_RETRY) {
				fprintf(out, "\n");
				lafe_warnc(0, "%s",
				    archive_error_string(a));
			}
			if (r == ARCHIVE_FATAL) {
				fprintf(out, "\n");
				lafe_warnc(0, "%s",
				    archive_error_string(a));
				bsdtar->return_value = 1;
				break;
			}
			fprintf(out, "\n");
		} else {
			/* Note: some rewrite failures prevent extraction. */
			if (edit_pathname(bsdtar, entry))
				continue; /* Excluded by a rewrite failure. */

			if (bsdtar->option_interactive &&
			    !yes("extract '%s'", archive_entry_pathname(entry)))
				continue;

			/*
			 * Format here is from SUSv2, including the
			 * deferred '\n'.
			 */
			if (bsdtar->verbose) {
				safe_fprintf(stderr, "x %s",
				    archive_entry_pathname(entry));
				fflush(stderr);
			}

			/* TODO siginfo_printinfo(bsdtar, 0); */

			if (bsdtar->option_stdout)
				r = archive_read_data_into_fd(a, 1);
			else
				r = archive_read_extract2(a, entry, writer);
			if (r != ARCHIVE_OK) {
				if (!bsdtar->verbose)
					safe_fprintf(stderr, "%s",
					    archive_entry_pathname(entry));
				safe_fprintf(stderr, ": %s",
				    archive_error_string(a));
				if (!bsdtar->verbose)
					fprintf(stderr, "\n");
				bsdtar->return_value = 1;
			}
			if (bsdtar->verbose)
				fprintf(stderr, "\n");
			if (r == ARCHIVE_FATAL)
				break;
		}
	}


	r = archive_read_close(a);
	if (r != ARCHIVE_OK)
		lafe_warnc(0, "%s", archive_error_string(a));
	if (r <= ARCHIVE_WARN)
		bsdtar->return_value = 1;

	if (bsdtar->verbose > 2)
		fprintf(stdout, "Archive Format: %s,  Compression: %s\n",
		    archive_format_name(a), archive_filter_name(a, 0));

	archive_read_free(a);
}
Пример #20
0
/*
 * Handle 'x' and 't' modes.
 */
static void
read_archive(struct bsdtar *bsdtar, char mode)
{
	struct progress_data	progress_data;
	FILE			 *out;
	struct archive		 *a;
	struct archive_entry	 *entry;
	const struct stat	 *st;
	int			  r;

	while (*bsdtar->argv) {
		lafe_include(&bsdtar->matching, *bsdtar->argv);
		bsdtar->argv++;
	}

	if (bsdtar->names_from_file != NULL)
		lafe_include_from_file(&bsdtar->matching,
		    bsdtar->names_from_file, bsdtar->option_null);

	a = archive_read_new();
	if (bsdtar->compress_program != NULL)
		archive_read_support_compression_program(a, bsdtar->compress_program);
	else
		archive_read_support_compression_all(a);
	archive_read_support_format_all(a);
	if (ARCHIVE_OK != archive_read_set_options(a, bsdtar->option_options))
		lafe_errc(1, 0, "%s", archive_error_string(a));
	if (archive_read_open_file(a, bsdtar->filename,
	    bsdtar->bytes_per_block != 0 ? bsdtar->bytes_per_block :
	    DEFAULT_BYTES_PER_BLOCK))
		lafe_errc(1, 0, "Error opening archive: %s",
		    archive_error_string(a));

	do_chdir(bsdtar);

	if (mode == 'x') {
		/* Set an extract callback so that we can handle SIGINFO. */
		progress_data.bsdtar = bsdtar;
		progress_data.archive = a;
		archive_read_extract_set_progress_callback(a, progress_func,
		    &progress_data);
	}

	if (mode == 'x' && bsdtar->option_chroot) {
#if HAVE_CHROOT
		if (chroot(".") != 0)
			lafe_errc(1, errno, "Can't chroot to \".\"");
#else
		lafe_errc(1, 0,
		    "chroot isn't supported on this platform");
#endif
	}

	for (;;) {
		/* Support --fast-read option */
		if (bsdtar->option_fast_read &&
		    lafe_unmatched_inclusions(bsdtar->matching) == 0)
			break;

		r = archive_read_next_header(a, &entry);
		progress_data.entry = entry;
		if (r == ARCHIVE_EOF)
			break;
		if (r < ARCHIVE_OK)
			lafe_warnc(0, "%s", archive_error_string(a));
		if (r <= ARCHIVE_WARN)
			bsdtar->return_value = 1;
		if (r == ARCHIVE_RETRY) {
			/* Retryable error: try again */
			lafe_warnc(0, "Retrying...");
			continue;
		}
		if (r == ARCHIVE_FATAL)
			break;

		if (bsdtar->uid >= 0) {
			archive_entry_set_uid(entry, bsdtar->uid);
			archive_entry_set_uname(entry, NULL);
		}
		if (bsdtar->gid >= 0) {
			archive_entry_set_gid(entry, bsdtar->gid);
			archive_entry_set_gname(entry, NULL);
		}
		if (bsdtar->uname)
			archive_entry_set_uname(entry, bsdtar->uname);
		if (bsdtar->gname)
			archive_entry_set_gname(entry, bsdtar->gname);

		/*
		 * Exclude entries that are too old.
		 */
		st = archive_entry_stat(entry);
		if (bsdtar->newer_ctime_sec > 0) {
			if (st->st_ctime < bsdtar->newer_ctime_sec)
				continue; /* Too old, skip it. */
			if (st->st_ctime == bsdtar->newer_ctime_sec
			    && ARCHIVE_STAT_CTIME_NANOS(st)
			    <= bsdtar->newer_ctime_nsec)
				continue; /* Too old, skip it. */
		}
		if (bsdtar->newer_mtime_sec > 0) {
			if (st->st_mtime < bsdtar->newer_mtime_sec)
				continue; /* Too old, skip it. */
			if (st->st_mtime == bsdtar->newer_mtime_sec
			    && ARCHIVE_STAT_MTIME_NANOS(st)
			    <= bsdtar->newer_mtime_nsec)
				continue; /* Too old, skip it. */
		}

		/*
		 * Note that pattern exclusions are checked before
		 * pathname rewrites are handled.  This gives more
		 * control over exclusions, since rewrites always lose
		 * information.  (For example, consider a rewrite
		 * s/foo[0-9]/foo/.  If we check exclusions after the
		 * rewrite, there would be no way to exclude foo1/bar
		 * while allowing foo2/bar.)
		 */
		if (lafe_excluded(bsdtar->matching, archive_entry_pathname(entry)))
			continue; /* Excluded by a pattern test. */

		if (mode == 't') {
			/* Perversely, gtar uses -O to mean "send to stderr"
			 * when used with -t. */
			out = bsdtar->option_stdout ? stderr : stdout;

			/*
			 * TODO: Provide some reasonable way to
			 * preview rewrites.  gtar always displays
			 * the unedited path in -t output, which means
			 * you cannot easily preview rewrites.
			 */
			if (bsdtar->verbose < 2)
				safe_fprintf(out, "%s",
				    archive_entry_pathname(entry));
			else
				list_item_verbose(bsdtar, out, entry);
			fflush(out);
			r = archive_read_data_skip(a);
			if (r == ARCHIVE_WARN) {
				fprintf(out, "\n");
				lafe_warnc(0, "%s",
				    archive_error_string(a));
			}
			if (r == ARCHIVE_RETRY) {
				fprintf(out, "\n");
				lafe_warnc(0, "%s",
				    archive_error_string(a));
			}
			if (r == ARCHIVE_FATAL) {
				fprintf(out, "\n");
				lafe_warnc(0, "%s",
				    archive_error_string(a));
				bsdtar->return_value = 1;
				break;
			}
			fprintf(out, "\n");
		} else {
			/* Note: some rewrite failures prevent extraction. */
			if (edit_pathname(bsdtar, entry))
				continue; /* Excluded by a rewrite failure. */

			if (bsdtar->option_interactive &&
			    !yes("extract '%s'", archive_entry_pathname(entry)))
				continue;

			/*
			 * Format here is from SUSv2, including the
			 * deferred '\n'.
			 */
			if (bsdtar->verbose) {
				safe_fprintf(stderr, "x %s",
				    archive_entry_pathname(entry));
				fflush(stderr);
			}

			// TODO siginfo_printinfo(bsdtar, 0);

			if (bsdtar->option_stdout)
				r = archive_read_data_into_fd(a, 1);
			else
				r = archive_read_extract(a, entry,
				    bsdtar->extract_flags);
			if (r != ARCHIVE_OK) {
				if (!bsdtar->verbose)
					safe_fprintf(stderr, "%s",
					    archive_entry_pathname(entry));
				safe_fprintf(stderr, ": %s",
				    archive_error_string(a));
				if (!bsdtar->verbose)
					fprintf(stderr, "\n");
				bsdtar->return_value = 1;
			}
			if (bsdtar->verbose)
				fprintf(stderr, "\n");
			if (r == ARCHIVE_FATAL)
				break;
		}
	}


	r = archive_read_close(a);
	if (r != ARCHIVE_OK)
		lafe_warnc(0, "%s", archive_error_string(a));
	if (r <= ARCHIVE_WARN)
		bsdtar->return_value = 1;

	if (bsdtar->verbose > 2)
		fprintf(stdout, "Archive Format: %s,  Compression: %s\n",
		    archive_format_name(a), archive_compression_name(a));

	archive_read_finish(a);
}
Пример #21
0
/*
 * Write user-specified files/dirs to opened archive.
 */
static void
write_archive(struct archive *a, struct bsdtar *bsdtar)
{
	const char *arg;
	struct archive_entry *entry, *sparse_entry;

	/* Choose a suitable copy buffer size */
	bsdtar->buff_size = 64 * 1024;
	while (bsdtar->buff_size < (size_t)bsdtar->bytes_per_block)
	  bsdtar->buff_size *= 2;
	/* Try to compensate for space we'll lose to alignment. */
	bsdtar->buff_size += 16 * 1024;

	/* Allocate a buffer for file data. */
	if ((bsdtar->buff = malloc(bsdtar->buff_size)) == NULL)
		lafe_errc(1, 0, "cannot allocate memory");

	if ((bsdtar->resolver = archive_entry_linkresolver_new()) == NULL)
		lafe_errc(1, 0, "cannot create link resolver");
	archive_entry_linkresolver_set_strategy(bsdtar->resolver,
	    archive_format(a));
	if ((bsdtar->diskreader = archive_read_disk_new()) == NULL)
		lafe_errc(1, 0, "Cannot create read_disk object");
	archive_read_disk_set_standard_lookup(bsdtar->diskreader);

	if (bsdtar->names_from_file != NULL)
		archive_names_from_file(bsdtar, a);

	while (*bsdtar->argv) {
		arg = *bsdtar->argv;
		if (arg[0] == '-' && arg[1] == 'C') {
			arg += 2;
			if (*arg == '\0') {
				bsdtar->argv++;
				arg = *bsdtar->argv;
				if (arg == NULL) {
					lafe_warnc(0, "%s",
					    "Missing argument for -C");
					bsdtar->return_value = 1;
					goto cleanup;
				}
				if (*arg == '\0') {
					lafe_warnc(0,
					    "Meaningless argument for -C: ''");
					bsdtar->return_value = 1;
					goto cleanup;
				}
			}
			set_chdir(bsdtar, arg);
		} else {
			if (*arg != '/' && (arg[0] != '@' || arg[1] != '/'))
				do_chdir(bsdtar); /* Handle a deferred -C */
			if (*arg == '@') {
				if (append_archive_filename(bsdtar, a,
				    arg + 1) != 0)
					break;
			} else
				write_hierarchy(bsdtar, a, arg);
		}
		bsdtar->argv++;
	}

	entry = NULL;
	archive_entry_linkify(bsdtar->resolver, &entry, &sparse_entry);
	while (entry != NULL) {
		write_file(bsdtar, a, entry);
		archive_entry_free(entry);
		entry = NULL;
		archive_entry_linkify(bsdtar->resolver, &entry, &sparse_entry);
	}

	if (archive_write_close(a)) {
		lafe_warnc(0, "%s", archive_error_string(a));
		bsdtar->return_value = 1;
	}

cleanup:
	/* Free file data buffer. */
	free(bsdtar->buff);
	archive_entry_linkresolver_free(bsdtar->resolver);
	bsdtar->resolver = NULL;
	archive_read_free(bsdtar->diskreader);
	bsdtar->diskreader = NULL;

	if (bsdtar->option_totals) {
		fprintf(stderr, "Total bytes written: %s\n",
		    tar_i64toa(archive_position_compressed(a)));
	}

	archive_write_free(a);
}
Пример #22
0
void addFilespec(FILE *fd, int squash_uids, int squash_perms)
{

	unsigned long rmode, mode, uid, gid, major, minor, i;
	unsigned long start, increment, count, octmode, decmode;
	char *c, *dir, *name, *dname = NULL, *path = NULL, *path2 = NULL, *line = NULL;
	char type;
	size_t len;
	int argv, i2, overWrite = 0, lineno = 0;
	__u16 inodeType;

	while ( getline(&line, &len, fd) >= 0 ) {
		rmode = mode = uid = gid = major = minor = start = count = overWrite = 0;
		increment = 1;
		lineno++;

		if (( c = strchr(line, '#'))) *c = 0;
		if ( path ) {
			free( path ); path = NULL;
		}
		if ( path2 ) {
			free( path2 ); path2 = NULL;
		}

		argv = sscanf(line, "%" SCANF_PREFIX "s %c %ld %lu %lu %lu %lu %lu %lu %lu",
			      SCANF_STRING(path), &type, &rmode, &uid, &gid, &major, &minor,
			      &start, &increment, &count);

		if ( argv < 3 ) {
			if ( argv > 0 )
				log_warning("device table[%d]: bad format for entry '%s' [skip]", lineno, path);
			continue;
		}

		i2 = 0;
		octmode = rmode;
		decmode = 0;
		while ( octmode != 0 ) {
			decmode = decmode + (octmode % 10) * pow(8, i2++);
			octmode = octmode / 10;
		}

		if ( squash_uids ) uid = gid = 0;

		mode = decmode;
		path2 = strdup( path );
		name = basename( path );
		dir = dirname( path2 );

		if (( !strcmp(name, ".")) || ( !strcmp(name, "..")) || ( !strcmp(name, "/"))) {
			log_warning("device table[%d]: [skip]", lineno);
			continue;
		}

		log_action(ACT_CHDIR, dir, NULL, 0, 0, 0, 0, 0, 0, 0);
		if ( !do_chdir(dir)) {
			log_warning("device table[%d]: target directory '%s' for entry '%s' does not exist [skip]", lineno, dir, name);
			log_action(ACT_CHDIR, "/", NULL, 0, 0, 0, 0, 0, 0, 0);
			if ( !do_chdir("/"))
				log_error("[Filesystem error] cannot chdir to root");
			continue;
		}

		if (( type != 'd' ) && ( type != 'f' ) && ( type != 'p' ) && ( type != 'c' ) && ( type != 'b' ) && ( type != 's')) {
			log_warning("device table[%d]: bad type '%c' for entry '%s' [skip]", lineno, type, name);
			continue;
		}

		if (squash_perms) {
			mode &= ~( LINUX_S_IRWXG | LINUX_S_IRWXO );
			rmode &= ~( LINUX_S_IRWXG | LINUX_S_IRWXO);
		}

		if ( count > 0 ) {

			if ( dname ) {
				free( dname );
				dname = NULL;
			}

			unsigned len;
			len = strlen(name) + 10;
			dname = malloc(len + 1);

			for ( i = start; i < count; i++ ) {
				snprintf(dname, len, "%s%lu", name, i);

				if (( overWrite = name_to_inode(dname)))
					inodeType = inode_mode(dname);

				if (( type == 'd' ) && ( overWrite ) && ( !LINUX_S_ISDIR(inodeType)))
					log_error("[Remote fs mismatch] %s/%s exists but isn't a directory when it should be.", log_cwd(), dname);
				else if (( type != 'd' ) && ( overWrite )) {

					if ( LINUX_S_ISDIR(inodeType))
						log_error("[Remote fs mismatch] %s/%s exists but is a directory when it shouldn't be.", log_cwd(), dname);

					if ((!LINUX_S_ISREG(inodeType)) && (!LINUX_S_ISLNK(inodeType)) &&
					    (!LINUX_S_ISBLK(inodeType)) && (!LINUX_S_ISCHR(inodeType)) &&
					    (!LINUX_S_ISFIFO(inodeType)) && (!LINUX_S_ISSOCK(inodeType)))
						log_error("[Remote fs mismatch] Existing file %s/%s has unknown/unsupported type [0x%x].", log_cwd(), dname, inodeType);
				}

				switch ( type ) {
				case 'd':
					mode |= LINUX_S_IFDIR;
					log_action(ACT_MKDIR, dname, NULL, 0, 0, 0, 0, 0, 0, overWrite);

					if ( !overWrite )
						if ( !do_mkdir(dname))
							log_error("[Filesystem error] cannot mkdir %s/%s", log_cwd(), dname);

					break;

				case 'c':
				case 'b':
					if ( type == 'c' )
						mode |= LINUX_S_IFCHR;
					else
						mode |= LINUX_S_IFBLK;

					if ( overWrite ) {
						log_action(ACT_RM, dname, NULL, 0, 0, 0, 0, 0, 0, overWrite);
						if ( !do_rm(dname))
							log_error("[Filesystem error] cannot rm %s/%s", log_cwd(), dname);
					}

					log_action(ACT_MKNOD, dname, NULL, 0, 0, 0, type, major, minor + ((i * increment) - start), overWrite);
					if ( !do_mknod(dname, type, major, minor + ((i * increment) - start)))
						log_error("[Filesystem error] cannot mknod %s/%s", log_cwd(), dname);
					break;

				case 's':
				case 'p':
					if ( type == 's' )
						mode |= LINUX_S_IFSOCK;
					else mode |= LINUX_S_IFIFO;

					if ( overWrite ) {
						log_action(ACT_RM, dname, NULL, 0, 0, 0, 0, 0, 0, overWrite);
						if ( !do_rm(dname))
							log_error("[Filesystem error] cannot rm %s/%s", log_cwd(), dname);
					}

					log_action(ACT_MKNOD, dname, NULL, 0, 0, 0, type, 0, 0, overWrite);
					if ( !do_mknod(dname, type, 0, 0))
						log_error("[Filesystem error] cannot mknod %s/%s", log_cwd(), dname);

					break;
				}

				log_action(ACT_CHMOD, dname, NULL, rmode, 0, 0, 0, 0, 0, 0);
				if ( !do_chmod(dname, rmode))
					log_error("[Filesystem error] cannot chmod %s/%s", log_cwd(), dname);
				log_action(ACT_CHOWN, dname, NULL, 0, uid, gid, 0, 0, 0, 0);
				if ( !do_chown(dname, uid, gid))
					log_error("[Filesystem error] cannot chown %s/%s", log_cwd(), dname);
			}

			log_action(ACT_CHDIR, "/", NULL, 0, 0, 0, 0, 0, 0, 0);
			if ( !do_chdir("/"))
				log_error("[Filesystem error] cannot chdir to root");
			free(dname);
			dname = NULL;

		} else {

			if (( overWrite = name_to_inode(name)))
				inodeType = inode_mode(name);

			if (( type == 'd' ) && ( overWrite ) && ( !LINUX_S_ISDIR(inodeType)))
				log_error("[Remote fs mismatch] %s/%s exists but isn't a directory when it should be.", log_cwd(), dname);
			else if ( type != 'd' ) {
				if (( overWrite ) && ( LINUX_S_ISDIR(inodeType)))
					log_error("[Remote fs mismatch] %s/%s exists but is a directory when it shouldn't be.", log_cwd(), dname);

				if (( overWrite ) && (!LINUX_S_ISREG(inodeType)) && (!LINUX_S_ISLNK(inodeType)) &&
				    (!LINUX_S_ISBLK(inodeType)) && (!LINUX_S_ISCHR(inodeType)) &&
				    (!LINUX_S_ISFIFO(inodeType)) && (!LINUX_S_ISSOCK(inodeType)))
					log_error("[Remote fs mismatch] Existing file %s/%s has unknown/unsupported type [0x%x].",  log_cwd(), dname, inodeType);
			}

			switch ( type ) {
			case 'd':
				mode |= LINUX_S_IFDIR;
				log_action(ACT_MKDIR, name, NULL, 0, 0, 0, 0, 0, 0, overWrite);

				if ( !overWrite )
					if ( !do_mkdir(name))
						log_error("[Filesystem error] cannot mkdir %s/%s", log_cwd(), name);
				break;

			case 'c':
			case 'b':
				if ( type == 'c' )
					mode |= LINUX_S_IFCHR;
				else
					mode |= LINUX_S_IFBLK;

				if ( overWrite ) {
					log_action(ACT_RM, name, NULL, 0, 0, 0, 0, 0, 0, overWrite);
					if ( !do_rm(name))
						log_error("[Filesystem error] cannot rm %s/%s", log_cwd(), name);
				}

				log_action(ACT_MKNOD, name, NULL, 0, 0, 0, type, major, minor, overWrite);
				if ( !do_mknod(name, type, major, minor))
					log_error("[Filesystem error] cannot mknod %s/%s", log_cwd(), name);
				break;

			case 's':
			case 'p':
				if ( type == 's' )
					mode |= LINUX_S_IFSOCK;
				else mode |= LINUX_S_IFIFO;

				if ( overWrite ) {
					log_action(ACT_RM, name, NULL, 0, 0, 0, 0, 0, 0, overWrite);
					if ( !do_rm(name))
						log_error("[Filesystem error] cannot rm %s/%s", log_cwd(), name);
				}

				log_action(ACT_MKNOD, name, NULL, 0, 0, 0, type, 0, 0, overWrite);
				if ( !do_mknod(name, type, 0, 0))
					log_error("[Filesystem error] cannot mknod %s/%s", log_cwd(), name);
				break;
			}

			log_action(ACT_CHMOD, name, NULL, rmode, 0, 0, 0, 0, 0, 0);
			if ( !do_chmod(name, rmode))
				log_error("[Filesystem error] cannot chmod %s/%s", log_cwd(), name);
			log_action(ACT_CHOWN, name, NULL, 0, uid, gid, 0, 0, 0, 0);
			if ( !do_chown(name, uid, gid))
				log_error("[Filesystem error] cannot chown %s/%s", log_cwd(), name);
			log_action(ACT_CHDIR, "/", NULL, 0, 0, 0, 0, 0, 0, 0);
			if ( !do_chdir("/"))
				log_error("[Filesystem error] cannot chdir to root");
		}

	}


	if ( line ) {
		free( line ); line = NULL;
	}
	if ( path ) {
		free( path ); path = NULL;
	}
	if ( path2 ) {
		free( path2 ); path2 = NULL;
	}

}
Пример #23
0
/*
 * Write user-specified files/dirs to opened archive.
 */
static void
write_archive(struct archive *a, struct bsdtar *bsdtar)
{
	const char *arg;
	struct archive_entry *entry, *sparse_entry;

	/* We want to catch SIGINFO and SIGUSR1. */
	siginfo_init(bsdtar);

	/* Allocate a buffer for file data. */
	if ((bsdtar->buff = malloc(FILEDATABUFLEN)) == NULL)
		bsdtar_errc(bsdtar, 1, 0, "cannot allocate memory");

	if ((bsdtar->resolver = archive_entry_linkresolver_new()) == NULL)
		bsdtar_errc(bsdtar, 1, 0, "cannot create link resolver");
	archive_entry_linkresolver_set_strategy(bsdtar->resolver,
	    archive_format(a));
	if ((bsdtar->diskreader = archive_read_disk_new()) == NULL)
		bsdtar_errc(bsdtar, 1, 0, "Cannot create read_disk object");
	archive_read_disk_set_standard_lookup(bsdtar->diskreader);

	if (bsdtar->names_from_file != NULL)
		archive_names_from_file(bsdtar, a);

	while (*bsdtar->argv) {
		arg = *bsdtar->argv;
		if (arg[0] == '-' && arg[1] == 'C') {
			arg += 2;
			if (*arg == '\0') {
				bsdtar->argv++;
				arg = *bsdtar->argv;
				if (arg == NULL) {
					bsdtar_warnc(bsdtar, 1, 0,
					    "Missing argument for -C");
					bsdtar->return_value = 1;
					goto cleanup;
				}
			}
			set_chdir(bsdtar, arg);
		} else {
			if (*arg != '/' && (arg[0] != '@' || arg[1] != '/'))
				do_chdir(bsdtar); /* Handle a deferred -C */
			if (*arg == '@') {
				if (append_archive_filename(bsdtar, a,
				    arg + 1) != 0)
					break;
			} else
#if defined(_WIN32) && !defined(__CYGWIN__)
				write_hierarchy_win(bsdtar, a, arg,
				    write_hierarchy);
#else
				write_hierarchy(bsdtar, a, arg);
#endif
		}
		bsdtar->argv++;
	}

	entry = NULL;
	archive_entry_linkify(bsdtar->resolver, &entry, &sparse_entry);
	while (entry != NULL) {
		write_entry_backend(bsdtar, a, entry);
		archive_entry_free(entry);
		entry = NULL;
		archive_entry_linkify(bsdtar->resolver, &entry, &sparse_entry);
	}

	if (archive_write_close(a)) {
		bsdtar_warnc(bsdtar, 0, "%s", archive_error_string(a));
		bsdtar->return_value = 1;
	}

cleanup:
	/* Free file data buffer. */
	free(bsdtar->buff);
	archive_entry_linkresolver_free(bsdtar->resolver);
	bsdtar->resolver = NULL;
	archive_read_finish(bsdtar->diskreader);
	bsdtar->diskreader = NULL;

	if (bsdtar->option_totals) {
		fprintf(stderr, "Total bytes written: " BSDTAR_FILESIZE_PRINTF "\n",
		    (BSDTAR_FILESIZE_TYPE)archive_position_compressed(a));
	}

	archive_write_finish(a);

	/* Restore old SIGINFO + SIGUSR1 handlers. */
	siginfo_done(bsdtar);
}
Пример #24
0
void addPath(const char *path, int squash_uids, int squash_perms)
{
	size_t len;
	char *full_name = NULL, *lnk = NULL;
	struct dirent *file = NULL;
	DIR *direc = NULL;
	struct stat st;
	int overWrite;
	__u16 inodeType;

	direc = opendir(path);

	if ( !direc )
		log_error("[Local fs opendir] Cannot open directory %s", path);

	while (( file = readdir(direc)) != NULL ) {

		if (( !strcmp(file->d_name, "." )) || ( !strcmp(file->d_name, ".." )))
			continue;

		len = strlen(path) + strlen( file->d_name ) + 3;

		if ( full_name ) {
			free( full_name );
			full_name = NULL;
		}

		full_name = (char*)malloc(len + 2);
		if ( !full_name )
			log_error("[Local fs stat] Memory allocation error ( full_name --> %s/%s )", path, file->d_name);

		memset(full_name, 0, len + 2);
		snprintf(full_name, len, "%s/%s", path, file->d_name);

		lstat(full_name, &st);
		mode_t fmt = st.st_mode & S_IFMT;

		if ( squash_uids )
			st.st_uid = st.st_gid = 0;

		if ( squash_perms )
			st.st_mode &= ~( LINUX_S_IRWXG | LINUX_S_IRWXO );

		overWrite = name_to_inode( file->d_name );

		if ( st.st_nlink > 1 ) {
			if (( lnk = linklist_add(st.st_dev, st.st_ino, full_name + modPath_path_len))) {

				if ( overWrite ) {
					log_action(ACT_RM, file->d_name, NULL, 0, 0, 0, 0, 0, 0, overWrite);
					if ( !do_rm(file->d_name))
						log_error("[Filesystem error] cannot rm %s/%s", log_cwd(), file->d_name);
				}

				log_action(ACT_HARDLINK, file->d_name, lnk, 0, 0, 0, 0, 0, 0, overWrite);
				if (!do_hardlink(&st, lnk, file->d_name))
					log_error("[Filesystem error] cannot hardlink %s --> %s", file->d_name, lnk);
				continue;
			}
		}

		if ( overWrite )
			inodeType = inode_mode( file->d_name );

		if (( fmt == S_IFDIR ) && ( overWrite ) && ( !LINUX_S_ISDIR(inodeType)))
			log_error("[Remote fs mismatch] %s/%s exists but isn't a directory when it should be.", log_cwd(), file->d_name);
		else if (( fmt != S_IFDIR) && ( overWrite )) {
			if ( LINUX_S_ISDIR(inodeType))
				log_error("[Remote fs mismatch] %s/%s exists but is a directory when it shouldn't be.", log_cwd(), file->d_name);

			if ((!LINUX_S_ISREG(inodeType)) && (!LINUX_S_ISLNK(inodeType)) &&
			    (!LINUX_S_ISBLK(inodeType)) && (!LINUX_S_ISCHR(inodeType)) &&
			    (!LINUX_S_ISFIFO(inodeType)) && (!LINUX_S_ISSOCK(inodeType)))
				log_error("[Remote fs mismatch] Existing file %s/%s has unknown/unsupported type [0x%x].", log_cwd(), file->d_name);
		}

		switch ( fmt ) {
		case S_IFDIR:         // Directory
			log_action(ACT_MKDIR, file->d_name, NULL, 0, 0, 0, 0, 0, 0, overWrite);

			if ( !overWrite )
				if ( !do_mkdir( &st, file->d_name ))
					log_error("[Filesystem error] cannot mkdir %s/%s", log_cwd(), file->d_name);

			log_action(ACT_CHMODE, file->d_name, NULL, st.st_mode, 0, 0, 0, 0, 0, overWrite);
			if ( !do_chmode(file->d_name, st.st_mode))
				log_error("[Filesystem error] Failed to chmode 0x%x for directory %s/%s", st.st_mode, log_cwd(), file->d_name);
			log_action(ACT_CHOWN, file->d_name, NULL, 0, st.st_uid, st.st_gid, 0, 0, 0, 0);
			if ( !do_chown(file->d_name, st.st_uid, st.st_gid))
				log_error("[Filesystem error] Failed to chown %ld, %ld for directory %s/%s", st.st_uid, st.st_gid, log_cwd(), file->d_name);

			log_action(ACT_CHDIR, file->d_name, NULL, 0, 0, 0, 0, 0, 0, 0);
			if ( !do_chdir( file->d_name ))
				log_error("[Filesystem error] cannot chdir to newly created %s/%s", log_cwd(), file->d_name);

			addPath(full_name, squash_uids, squash_perms);

			log_action(ACT_CHDIR, "..", NULL, 0, 0, 0, 0, 0, 0, 0);
			if ( !do_chdir(".."))
				log_error("[Filesystem error] cannot chdir to parent directory");
			break;

		case S_IFREG:         // Regular file

			if ( overWrite ) {
				log_action(ACT_RM, file->d_name, NULL, 0, 0, 0, 0, 0, 0, overWrite);
				if ( !do_rm(file->d_name))
					log_error("[Filesystem error] cannot rm %s/%s", log_cwd(), file->d_name);
			}

			log_action(ACT_WRITE, file->d_name, NULL, 0, 0, 0, 0, 0, 0, overWrite);
			if ( !do_write(full_name, file->d_name))
				log_error("[Filesystem error] cannot write %s/%s", log_cwd(), file->d_name);
			break;

		case S_IFLNK:         // Symbolic link

			lnk = (char*)malloc(MAX_PATHSIZE + 2);
			if ( !lnk )
				log_error("[symlink] Memory allocation error (lnk)");
			int len = readlink(full_name, lnk, MAX_PATHSIZE);
			if ( len == -1 ) {
				free(lnk);
				log_error("[Local filesystem error] Cannot read destination for link %s/%s", log_cwd(), file->d_name);
			} else lnk[len] = '\0';

			if ( overWrite ) {
				log_action(ACT_RM, file->d_name, NULL, 0, 0, 0, 0, 0, 0, overWrite);
				if ( !do_rm(file->d_name))
					log_error("[Filesystem error] cannot rm %s/%s", log_cwd(), file->d_name);
			}

			log_action(ACT_SYMLINK, file->d_name, lnk, 0, 0, 0, 0, 0, 0, overWrite);
			if ( !do_symlink(&st, lnk, file->d_name))
				log_error("[Filesystem error] cannot symlink %s/%s --> %s", log_cwd(), file->d_name, lnk);

			free(lnk);
			break;

		case S_IFBLK:           // Block device node
		case S_IFCHR:           // Character device node
		case S_IFSOCK:          // socket
		case S_IFIFO:           // fifo

			if ( overWrite ) {
				log_action(ACT_RM, file->d_name, NULL, 0, 0, 0, 0, 0, 0, overWrite);
				if ( !do_rm(file->d_name))
					log_error("[Filesystem error] cannot rm %s/%s", log_cwd(), file->d_name);
			}

			char nodetype = ( fmt == S_IFBLK ? 'b' : ( fmt == S_IFCHR ? 'c' : ( fmt == S_IFSOCK ? 's' : 'p' )));
			unsigned long major = 0, minor = 0;

			if (( nodetype == 'b' ) || ( nodetype == 'c' )) {
				major = (long)major(st.st_rdev);
				minor = (long)minor(st.st_rdev);
			}

			log_action(ACT_MKNOD, file->d_name, NULL, 0, 0, 0, nodetype, major, minor, overWrite);
			if ( !do_mknod(file->d_name, nodetype, major, minor))
				log_error("[Filesystem error] cannot mknod %c %ld,%ld %s/%s", log_cwd(), nodetype, major, minor, log_cwd(), file->d_name);
			break;
		}

		if ( fmt != S_IFDIR ) { // Not dir ?
			log_action(ACT_CHMODE, file->d_name, NULL, st.st_mode, 0, 0, 0, 0, 0, overWrite);
			if ( !do_chmode(file->d_name, st.st_mode))
				log_error("[Filesystem error] Failed to chmode 0x%x for file %s/%s", st.st_mode, log_cwd(), file->d_name);
			log_action(ACT_CHOWN, file->d_name, NULL, 0, st.st_uid, st.st_gid, 0, 0, 0, 0);
			if ( !do_chown(file->d_name, st.st_uid, st.st_gid))
				log_error("[Filesystem error] Failed to chown %ld, %ld for file %s/%s", st.st_uid, st.st_gid, log_cwd(), file->d_name);
		}

		if ( full_name ) {
			free( full_name );
			full_name = NULL;
		}
	}

	closedir(direc);

}
Пример #25
0
int main(int argc, char** argv)
{
        int c, i, mypid;
        int opt_depth = 1;
        int opt_mknod = 0;

        static struct option long_opt[] = {
                {"depth", 1, 0, 'd' },
                {"help", 0, 0, 'h' },
                {"mknod", 0, 0, 'm' },
                {"output", 1, 0, 'o' },
                {"trace", 1, 0, 't' },
                {"verbose", 0, 0, 'v' },
                {0,0,0,0}
        };

        char *outputfilename = NULL;
        char *base_pathname;
        char pathname[PATH_MAX];
        char mark_buf[PATH_MAX + 50];
        char mycwd[PATH_MAX];
        char *pname = argv[0];

        while ((c = getopt_long(argc, argv, "d:mhvo:", long_opt, NULL)) != -1) {
                switch (c) {
                case 'd':
                        opt_depth = atoi(optarg);
                        if ((opt_depth == 0) || (opt_depth > 1100))
                                usage(pname);
                        break;
                case 'm':
                        opt_mknod = 1;
                        break;
                case 't':
                        opt_trace = 1;
                        break;
                case 'v':
                        opt_verbose = 1;
                        break;
                case 'o':
                        outputfilename = optarg;
                        break;
                case 'h':
                case '?':
                case ':':
                default:
                        usage(pname);
                        break;
                }
        }

        if (optind != (argc - 1))
                usage(pname);

        base_pathname = argv[optind];
        mypid = getpid();

        if (!getcwd(&mycwd[0], sizeof(mycwd))) {
                fprintf(stderr, "%s: unable to getcwd()\n", pname);
                exit(1);
        }

        printf("%s(pid=%d) depth=%d mknod=%d, basepathname=%s, trace=%d\n",
               pname, mypid, opt_depth, opt_mknod, base_pathname, opt_trace);

        if (outputfilename)
                printf("outputfilename=%s\n", outputfilename);

        if (opt_trace) {
                ltrace_start();
                ltrace_clear();
                snprintf(mark_buf, PATH_MAX, "Initialize - mkdir %s; chdir %s",
                         base_pathname, base_pathname);
                ltrace_mark(2, mark_buf);
        }

        if (do_mkdir(base_pathname)!=0)
                exit(1);
        if (do_chdir(base_pathname)!=0)
                exit(1);

        /* Create directory tree with depth level of subdirectories */

        if (opt_trace) {
                snprintf(mark_buf, PATH_MAX,
                         "Create Directory Tree (depth %d)", opt_depth);
                ltrace_mark(2, mark_buf);
        }

        for (i = 0; i < opt_depth; i++) {
                snprintf(pathname, sizeof(pathname), "%d", i + 1);

                if (i == (opt_depth - 1)) {
                        /* Last Iteration */

                        if (opt_trace) {
                                snprintf(mark_buf, PATH_MAX,
                                         "Tree Leaf (%d) %s/stat", i,
                                         (opt_mknod ? "mknod" : "mkdir"));
                                ltrace_mark(3, mark_buf);
                        }

                        if (opt_mknod)
                                do_mknod(pathname);
                        else
                                do_mkdir(pathname);
                        /* Now stat it */
                        do_stat(pathname);
                } else {
                        /* Not Leaf */

                        if (opt_trace) {
                                snprintf(mark_buf, sizeof(mark_buf),
                                         "Tree Level (%d) mkdir/stat/chdir", i);
                                ltrace_mark(3, mark_buf);
                        }

                        do_mkdir(pathname);
                        do_stat(pathname);
                        do_chdir(pathname);
                }
        }

        /* Stat through directory tree with fullpaths */

        if (opt_trace) {
                snprintf(mark_buf, PATH_MAX, "Walk Directory Tree");
                ltrace_mark(2, mark_buf);
        }

        do_chdir(base_pathname);

        strncpy(pathname, base_pathname, sizeof(pathname));

        c = strlen(base_pathname);
        for (i = 0; i < opt_depth; i++) {
                c += snprintf(pathname + c, sizeof(pathname) - c, "/%d", i+1);

                if (opt_trace) {
                        snprintf(mark_buf, PATH_MAX, "stat %s", pathname);
                        ltrace_mark(2, mark_buf);
                }

                do_stat(pathname);
        }

        if (opt_trace && outputfilename) {
                    ltrace_write_file(outputfilename);
                    ltrace_add_processnames(outputfilename);
                    ltrace_stop();
        }

        do_chdir(base_pathname);

        printf("%s (pid=%d) done.\n", pname, mypid);

        return 0;
}