Ejemplo n.º 1
0
void run_tests2(void)
{
  int i;
  int64_t arr[SIZE];
  int64_t dst[SIZE];
  double start_time;
  double end_time;
  double total_time;

  printf("Running tests - 2\n");
  srand48(SEED);
  total_time = 0.0;
  for (i = 0; i < RUNS; i++) {
    fill(arr, SIZE);
    memcpy(dst, arr, sizeof(int64_t) * SIZE);
    start_time = utime();

    qsort(dst, SIZE, sizeof(int64_t), simple_cmp2);

    end_time = utime();
    total_time += end_time - start_time;
    verify2(dst, SIZE);
  }
  printf("stdlib qsort time: %.2f us per iteration\n", total_time / RUNS);

#ifndef __linux__
  srand48(SEED);
  total_time = 0.0;
  for (i = 0; i < RUNS; i++) {
    fill(arr, SIZE);
    memcpy(dst, arr, sizeof(int64_t) * SIZE);
    start_time = utime();

    heapsort(dst, SIZE, sizeof(int64_t), simple_cmp2);

    end_time = utime();
    total_time += end_time - start_time;
    verify2(dst, SIZE);
  }
  printf("stdlib heapsort time: %.2f us per iteration\n", total_time / RUNS);

  srand48(SEED);
  total_time = 0.0;
  for (i = 0; i < RUNS; i++) {
    fill(arr, SIZE);
    memcpy(dst, arr, sizeof(int64_t) * SIZE);
    start_time = utime();

    mergesort(dst, SIZE, sizeof(int64_t), simple_cmp2);

    end_time = utime();
    total_time += end_time - start_time;
    verify2(dst, SIZE);
  }
  printf("stdlib mergesort time: %.2f us per iteration\n", total_time / RUNS);
#endif

  srand48(SEED);
  total_time = 0.0;
  for (i = 0; i < RUNS; i++) {
    fill(arr, SIZE);
    memcpy(dst, arr, sizeof(int64_t) * SIZE);
    start_time = utime();

    sorter2_quick_sort(dst, SIZE);

    end_time = utime();
    total_time += end_time - start_time;
    verify2(dst, SIZE);
  }
  printf("quick sort time: %.2f us per iteration\n", total_time / RUNS);


  srand48(SEED);
  total_time = 0.0;
  for (i = 0; i < RUNS; i++) {
    fill(arr, SIZE);
    memcpy(dst, arr, sizeof(int64_t) * SIZE);
    start_time = utime();

    sorter2_bubble_sort(dst, SIZE);

    end_time = utime();
    total_time += end_time - start_time;
    verify2(dst, SIZE);
  }
  printf("bubble sort time: %.2f us per iteration\n", total_time / RUNS);

  srand48(SEED);
  total_time = 0.0;
  for (i = 0; i < RUNS; i++) {
    fill(arr, SIZE);
    memcpy(dst, arr, sizeof(int64_t) * SIZE);
    start_time = utime();

    sorter2_merge_sort(dst, SIZE);

    end_time = utime();
    total_time += end_time - start_time;
    verify2(dst, SIZE);
  }
  printf("merge sort time: %.2f us per iteration\n", total_time / RUNS);

  srand48(SEED);
  total_time = 0.0;
  for (i = 0; i < RUNS; i++) {
    fill(arr, SIZE);
    memcpy(dst, arr, sizeof(int64_t) * SIZE);
    start_time = utime();

    sorter2_binary_insertion_sort(dst, SIZE);

    end_time = utime();
    total_time += end_time - start_time;
    verify2(dst, SIZE);
  }
  printf("binary insertion sort time: %.2f us per iteration\n", total_time / RUNS);

  srand48(SEED);
  total_time = 0.0;
  for (i = 0; i < RUNS; i++) {
    fill(arr, SIZE);
    memcpy(dst, arr, sizeof(int64_t) * SIZE);
    start_time = utime();

    sorter2_heap_sort(dst, SIZE);

    end_time = utime();
    total_time += end_time - start_time;
    verify2(dst, SIZE);
  }
  printf("heap sort time: %.2f us per iteration\n", total_time / RUNS);

  srand48(SEED);
  total_time = 0.0;
  for (i = 0; i < RUNS; i++) {
    fill(arr, SIZE);
    memcpy(dst, arr, sizeof(int64_t) * SIZE);
    start_time = utime();

    sorter2_shell_sort(dst, SIZE);

    end_time = utime();
    total_time += end_time - start_time;
    verify2(dst, SIZE);
  }
  printf("shell sort time: %.2f us per iteration\n", total_time / RUNS);

  srand48(SEED);
  total_time = 0.0;
  for (i = 0; i < RUNS; i++) {
    fill(arr, SIZE);
    memcpy(dst, arr, sizeof(int64_t) * SIZE);
    start_time = utime();

    sorter2_tim_sort(dst, SIZE);

    end_time = utime();
    total_time += end_time - start_time;
    verify2(dst, SIZE);
  }
  printf("tim sort time: %.2f us per iteration\n", total_time / RUNS);
}
Ejemplo n.º 2
0
static int
set_info_func (CameraFilesystem *fs, const char *folder, const char *file,
	       CameraFileInfo info, void *data, GPContext *context)
{
	int retval;
	char path[1024];
	Camera *camera = (Camera*)data;

	retval = _get_path (camera->port, folder, file, path, sizeof(path));
	if (retval < GP_OK)
		return retval;

	/* We don't support updating permissions (yet) */
	if (info.file.fields & GP_FILE_INFO_PERMISSIONS)
		return (GP_ERROR_NOT_SUPPORTED);

	if (info.file.fields & GP_FILE_INFO_MTIME) {
		struct utimbuf utimbuf;

		utimbuf.actime  = info.file.mtime;
		utimbuf.modtime = info.file.mtime;
		if (utime (path, &utimbuf) != 0) {
			gp_context_error (context, _("Could not change "
				"time of file '%s' in '%s' (%m)."),
				file, folder);
			return (GP_ERROR);
		}
	}

#if 0 /* implement this using new api -Marcus */
	if (info.file.fields & GP_FILE_INFO_NAME) {
        	if (!strcasecmp (info.file.name, file))
        	        return (GP_OK);

	        /* We really have to rename the poor file... */
		if (strlen (folder) == 1) {
			snprintf (path_old, sizeof (path_old), "/%s",
				  file);
			snprintf (path_new, sizeof (path_new), "/%s",
				  info.file.name);
		} else {
			snprintf (path_old, sizeof (path_old), "%s/%s",
				  folder, file);
			snprintf (path_new, sizeof (path_new), "%s/%s",
				  folder, info.file.name);
		}
                retval = rename (path_old, path_new);
		if (retval != 0) {
	                switch (errno) {
	                case EISDIR:
	                        return (GP_ERROR_DIRECTORY_EXISTS);
	                case EEXIST:
	                        return (GP_ERROR_FILE_EXISTS);
	                case EINVAL:
	                        return (GP_ERROR_BAD_PARAMETERS);
	                case EIO:
	                        return (GP_ERROR_IO);
	                case ENOMEM:
	                        return (GP_ERROR_NO_MEMORY);
	                case ENOENT:
	                        return (GP_ERROR_FILE_NOT_FOUND);
	                default:
	                        return (GP_ERROR);
	                }
	        }
	}
#endif

        return (GP_OK);
}
Ejemplo n.º 3
0
MODRET site_misc_utime(cmd_rec *cmd) {
  if (cmd->argc < 2)
    return DECLINED(cmd);

  if (strcasecmp(cmd->argv[1], "UTIME") == 0) {
    register unsigned int i;
    char c, *p, *path = "";
    unsigned int year, month, day, hour, min;
    struct utimbuf tmbuf;
    unsigned char *authenticated;

    if (cmd->argc < 4)
      return DECLINED(cmd);

    authenticated = get_param_ptr(cmd->server->conf, "authenticated", FALSE);

    if (!authenticated || *authenticated == FALSE) {
      pr_response_add_err(R_530, "Please login with USER and PASS");
      return ERROR(cmd);
    }

    if (strlen(cmd->argv[2]) != 12) {
      pr_response_add_err(R_500, "%s: %s", cmd->arg, strerror(EINVAL));
      return ERROR(cmd);
    }

    for (i = 3; i < cmd->argc; i++)
      path = pstrcat(cmd->tmp_pool, path, *path ? " " : "", cmd->argv[i], NULL);

    if (!dir_check(cmd->tmp_pool, "SITE_UTIME", G_WRITE, path, NULL)) {
      pr_response_add_err(R_550, "%s: %s", cmd->arg, strerror(EPERM));
      return ERROR(cmd);
    }

    if (site_misc_check_filters(cmd, path) < 0) {
      pr_response_add_err(R_550, "%s: %s", cmd->arg, strerror(EPERM));
      return ERROR(cmd);
    }

    p = cmd->argv[2];
    c = cmd->argv[2][4];
    cmd->argv[2][4] = '\0';
    year = atoi(p);
   
    cmd->argv[2][4] = c;
    p = &(cmd->argv[2][4]);
    c = cmd->argv[2][6];
    cmd->argv[2][6] = '\0';
    month = atoi(p);

    cmd->argv[2][6] = c;
    p = &(cmd->argv[2][6]);
    c = cmd->argv[2][8];
    cmd->argv[2][8] = '\0';
    day = atoi(p);

    cmd->argv[2][8] = c;
    p = &(cmd->argv[2][8]);
    c = cmd->argv[2][10];
    cmd->argv[2][10] = '\0';
    hour = atoi(p);

    cmd->argv[2][10] = c;
    p = &(cmd->argv[2][10]);
    min = atoi(p);

    tmbuf.actime = tmbuf.modtime = site_misc_mktime(year, month, day, hour,
      min);

    if (utime(path, &tmbuf) < 0) {
      pr_response_add_err(R_550, "%s: %s", cmd->arg, strerror(errno));
      return ERROR(cmd);
    }
 
    pr_response_add(R_200, "SITE %s command successful", cmd->argv[1]);
    return HANDLED(cmd);
  }

  if (strcasecmp(cmd->argv[1], "HELP") == 0)
    pr_response_add(R_214, "UTIME <sp> YYYYMMDDhhmm <sp> path");

  return DECLINED(cmd);
}
Ejemplo n.º 4
0
int main(int ac, char **av)
{
	struct stat stat_buf;	/* struct buffer to hold file info. */
	int lc;
	const char *msg;
	time_t modf_time, access_time;
	/* file modification/access time */

	msg = parse_opts(ac, av, NULL, NULL);
	if (msg != NULL) {
		tst_brkm(TBROK, NULL, "OPTION PARSING ERROR - %s", msg);

	}

	setup();

	/* set the expected errnos... */
	TEST_EXP_ENOS(exp_enos);

	for (lc = 0; TEST_LOOPING(lc); lc++) {

		tst_count = 0;

		/*
		 * Invoke utime(2) to set TEMP_FILE access and
		 * modification times to that specified by
		 * times argument.
		 */
		TEST(utime(TEMP_FILE, &times));

		if (TEST_RETURN == -1) {
			TEST_ERROR_LOG(TEST_ERRNO);
			tst_resm(TFAIL, "utime(%s) Failed, errno=%d : %s",
				 TEMP_FILE, TEST_ERRNO, strerror(TEST_ERRNO));
		} else {
			/*
			 * Get the modification and access times of
			 * temporary file using stat(2).
			 */
			if (stat(TEMP_FILE, &stat_buf) < 0) {
				tst_brkm(TFAIL, cleanup, "stat(2) of "
					 "%s failed, error:%d",
					 TEMP_FILE, TEST_ERRNO);
			}
			modf_time = stat_buf.st_mtime;
			access_time = stat_buf.st_atime;

			/* Now do the actual verification */
			if ((modf_time != NEW_TIME) ||
			    (access_time != NEW_TIME)) {
				tst_resm(TFAIL, "%s access and "
					 "modification times not set",
					 TEMP_FILE);
			} else {
				tst_resm(TPASS, "Functionality of "
					 "utime(%s, &times) successful",
					 TEMP_FILE);
			}
		}
		tst_count++;	/* incr TEST_LOOP counter */
	}

	cleanup();
	tst_exit();
}
Ejemplo n.º 5
0
int copy_file(const char *source, const char *dest, int flags)
{
	struct stat source_stat;
	struct stat dest_stat;
	int dest_exists = 0;
	int status = 0;

	if ((!(flags & FILEUTILS_PRESERVE_SYMLINKS) &&
			lstat(source, &source_stat) < 0) ||
			((flags & FILEUTILS_PRESERVE_SYMLINKS) &&
			 stat(source, &source_stat) < 0)) {
		perror_msg("%s", source);
		return -1;
	}

	if (lstat(dest, &dest_stat) < 0) {
		if (errno != ENOENT) {
			perror_msg("unable to stat `%s'", dest);
			return -1;
		}
	} else {
		if (source_stat.st_dev == dest_stat.st_dev &&
			source_stat.st_ino == dest_stat.st_ino) {
		error_msg("`%s' and `%s' are the same file", source, dest);
		return -1;
	}
		dest_exists = 1;
	}

	if (S_ISDIR(source_stat.st_mode)) {
		DIR *dp;
		struct dirent *d;
		mode_t saved_umask = 0;

		if (!(flags & FILEUTILS_RECUR)) {
			error_msg("%s: omitting directory", source);
			return -1;
		}

		/* Create DEST.  */
		if (dest_exists) {
			if (!S_ISDIR(dest_stat.st_mode)) {
				error_msg("`%s' is not a directory", dest);
				return -1;
			}
		} else {
			mode_t mode;
			saved_umask = umask(0);

			mode = source_stat.st_mode;
			if (!(flags & FILEUTILS_PRESERVE_STATUS))
				mode = source_stat.st_mode & ~saved_umask;
			mode |= S_IRWXU;

			if (mkdir(dest, mode) < 0) {
				umask(saved_umask);
				perror_msg("cannot create directory `%s'", dest);
				return -1;
			}

			umask(saved_umask);
		}

		/* Recursively copy files in SOURCE.  */
		if ((dp = opendir(source)) == NULL) {
			perror_msg("unable to open directory `%s'", source);
			status = -1;
			goto end;
		}

		while ((d = readdir(dp)) != NULL) {
			char *new_source, *new_dest;

			if (strcmp(d->d_name, ".") == 0 ||
					strcmp(d->d_name, "..") == 0)
				continue;

			new_source = concat_path_file(source, d->d_name);
			new_dest = concat_path_file(dest, d->d_name);
			if (copy_file(new_source, new_dest, flags) < 0)
				status = -1;
			free(new_source);
			free(new_dest);
		}
		/* closedir have only EBADF error, but "dp" not changes */
		closedir(dp);

		if (!dest_exists &&
				chmod(dest, source_stat.st_mode & ~saved_umask) < 0) {
			perror_msg("unable to change permissions of `%s'", dest);
			status = -1;
		}
	} else if (S_ISREG(source_stat.st_mode)) {
		FILE *sfp, *dfp=NULL;
#ifdef CONFIG_FEATURE_PRESERVE_HARDLINKS
		char *link_name;

		if (!(flags & FILEUTILS_PRESERVE_SYMLINKS) &&
				is_in_ino_dev_hashtable(&source_stat, &link_name)) {
			if (link(link_name, dest) < 0) {
				perror_msg("unable to link `%s'", dest);
				return -1;
			}

			return 0;
		}
#endif

		if ((sfp = wfopen(source, "r")) == NULL) {
			return -1;
		}

		if (dest_exists) {
			if (flags & FILEUTILS_INTERACTIVE) {
				fprintf(stderr, "%s: overwrite `%s'? ", applet_name, dest);
				if (!ask_confirmation()) {
					fclose (sfp);
					return 0;
				}
			}

			if ((dfp = fopen(dest, "w")) == NULL) {
				if (!(flags & FILEUTILS_FORCE)) {
					perror_msg("unable to open `%s'", dest);
					fclose (sfp);
					return -1;
				}

				if (unlink(dest) < 0) {
					perror_msg("unable to remove `%s'", dest);
					fclose (sfp);
					return -1;
				}

				dest_exists = 0;
			}
		}

		if (!dest_exists) {
			int fd;

			if ((fd = open(dest, O_WRONLY|O_CREAT, source_stat.st_mode)) < 0 ||
					(dfp = fdopen(fd, "w")) == NULL) {
				if (fd >= 0)
					close(fd);
				perror_msg("unable to open `%s'", dest);
				fclose (sfp);
				return -1;
			}
		}

		if (copy_file_chunk(sfp, dfp, -1) < 0)
			status = -1;

		if (fclose(dfp) < 0) {
			perror_msg("unable to close `%s'", dest);
			status = -1;
		}

		if (fclose(sfp) < 0) {
			perror_msg("unable to close `%s'", source);
			status = -1;
		}
			}
	else if (S_ISBLK(source_stat.st_mode) || S_ISCHR(source_stat.st_mode) ||
	    S_ISSOCK(source_stat.st_mode) || S_ISFIFO(source_stat.st_mode) ||
	    S_ISLNK(source_stat.st_mode)) {

		if (dest_exists &&
		       ((flags & FILEUTILS_FORCE) == 0 || unlink(dest) < 0)) {
				perror_msg("unable to remove `%s'", dest);
				return -1;

			}
	} else {
		error_msg("internal error: unrecognized file type");
		return -1;
		}
	if (S_ISBLK(source_stat.st_mode) || S_ISCHR(source_stat.st_mode) ||
	    S_ISSOCK(source_stat.st_mode)) {
		if (mknod(dest, source_stat.st_mode, source_stat.st_rdev) < 0) {
			perror_msg("unable to create `%s'", dest);
			return -1;
		}
	} else if (S_ISFIFO(source_stat.st_mode)) {
		if (mkfifo(dest, source_stat.st_mode) < 0) {
			perror_msg("cannot create fifo `%s'", dest);
			return -1;
		}
	} else if (S_ISLNK(source_stat.st_mode)) {
		char *lpath;

		lpath = xreadlink(source);
		if (symlink(lpath, dest) < 0) {
			perror_msg("cannot create symlink `%s'", dest);
			return -1;
		}
		free(lpath);

#if (__GLIBC__ >= 2) && (__GLIBC_MINOR__ >= 1)
		if (flags & FILEUTILS_PRESERVE_STATUS)
			if (lchown(dest, source_stat.st_uid, source_stat.st_gid) < 0)
				perror_msg("unable to preserve ownership of `%s'", dest);
#endif

#ifdef CONFIG_FEATURE_PRESERVE_HARDLINKS
		add_to_ino_dev_hashtable(&source_stat, dest);
#endif

		return 0;
	}

#ifdef CONFIG_FEATURE_PRESERVE_HARDLINKS
	add_to_ino_dev_hashtable(&source_stat, dest);
#endif

end:

	if (flags & FILEUTILS_PRESERVE_STATUS) {
		struct utimbuf times;

		times.actime = source_stat.st_atime;
		times.modtime = source_stat.st_mtime;
		if (utime(dest, &times) < 0)
			perror_msg("unable to preserve times of `%s'", dest);
		if (chown(dest, source_stat.st_uid, source_stat.st_gid) < 0) {
			source_stat.st_mode &= ~(S_ISUID | S_ISGID);
			perror_msg("unable to preserve ownership of `%s'", dest);
		}
		if (chmod(dest, source_stat.st_mode) < 0)
			perror_msg("unable to preserve permissions of `%s'", dest);
	}

	return status;
}
Ejemplo n.º 6
0
/* Retrieve a file 'file' of size 'size' by reading the contents of it from the 
 * socket 'sock' and write the file with the same name to directory 'directory'. 
 * Update the last modified time of this file to 'timestamp' on the filesystem.
 * @Param: sock the socket to read from.
 * @Param: directory the directory to write the file to.
 * @Param: size the size of the file being retrieved.
 * @Param: timestamp the last modified time to set to.
 * @Return: void.
 */
void get_file(int sock, char* directory, char* file, int size, long int timestamp){
	int readlength, readcount = 0, length;
	char buffer[CHUNKSIZE];
	char fullpath[CHUNKSIZE];
	FILE *fp;

	//Grab the full path to the file.
	strncpy(fullpath, directory, CHUNKSIZE);
	strcat(fullpath, "/");
	strncat(fullpath, file, CHUNKSIZE-strlen(fullpath));

	//Open the file. Overwite if it already exists.
	if((fp = fopen(fullpath, "w")) == NULL) {
		perror("fopen on get file: ");
		exit(1);
    }

	/* Length computes the size of the file to be read per read call.
	 * if the length happens to be more than CHUNKSIZE (256) then read only
	 * CHUNKSIZE at max for now.
	 */
	if((length = size) > CHUNKSIZE){
		length = CHUNKSIZE;
	}

	while( readcount < size ){

		/* Compute the reamining length to be read. If the reamining length happens
		 * to be more than CHUNKSIZE (256) then read only CHUNKSIZE at max for now
		 */
		length = size - readcount;
		if (length > CHUNKSIZE){
			length = CHUNKSIZE;
		}

		readlength = Readn(sock, &buffer, length);

		//Update how many bytes has been read yet.
		readcount += readlength;

		fwrite(buffer, readlength, 1, fp);
	
		//If there was an error with fwrite.
		if(ferror(fp)){
    		fprintf(stderr, "A write error occured.\n");
			Close(sock);
			exit(1);
		}
	}		
	
	if((fclose(fp))) {
		perror("fclose: ");
		exit(1);
    }	

	struct stat sbuf;
    struct utimbuf new_times;
	
	if(stat(fullpath, &sbuf) != 0) {
    	perror("stat");
    	exit(1);
    }
	
	//Update the last modified time to 'timestamp' for this file on the filesystem.
	new_times.actime = sbuf.st_atime; //Access time.
	new_times.modtime = (time_t)timestamp;
	
	if(utime(fullpath, &new_times) < 0) {
    	perror("utime");
    	exit(1);
    }
}
Ejemplo n.º 7
0
Archivo: file.c Proyecto: WebDrake/dmd
int File::write()
{
#if POSIX
    int fd;
    ssize_t numwritten;
    char *name;

    name = this->name->toChars();
    fd = open(name, O_CREAT | O_WRONLY | O_TRUNC, 0644);
    if (fd == -1)
        goto err;

    numwritten = ::write(fd, buffer, len);
    if (len != numwritten)
        goto err2;

    if (close(fd) == -1)
        goto err;

    if (touchtime)
    {   struct utimbuf ubuf;

        ubuf.actime = ((struct stat *)touchtime)->st_atime;
        ubuf.modtime = ((struct stat *)touchtime)->st_mtime;
        if (utime(name, &ubuf))
            goto err;
    }
    return 0;

err2:
    close(fd);
    ::remove(name);
err:
    return 1;
#elif _WIN32
    HANDLE h;
    DWORD numwritten;
    char *name;

    name = this->name->toChars();
    h = CreateFileA(name,GENERIC_WRITE,0,NULL,CREATE_ALWAYS,
        FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN,NULL);
    if (h == INVALID_HANDLE_VALUE)
        goto err;

    if (WriteFile(h,buffer,len,&numwritten,NULL) != TRUE)
        goto err2;

    if (len != numwritten)
        goto err2;

    if (touchtime) {
        SetFileTime(h, NULL, NULL, &((WIN32_FIND_DATAA *)touchtime)->ftLastWriteTime);
    }
    if (!CloseHandle(h))
        goto err;
    return 0;

err2:
    CloseHandle(h);
    DeleteFileA(name);
err:
    return 1;
#else
    assert(0);
#endif
}
Ejemplo n.º 8
0
static void proto_handle_get(conn_t* cn, const char* line) {
	struct stat st;

	// Reject filenames with just "." and ".."
	if(memcmp(line, ".\0", 2) == 0 || memcmp(line, "..\0", 3) == 0) {
		conn_printf(cn, "ERROR Protocol violation (%d)\n", __LINE__);
		conn_abort(cn);
		return;
	}

	if(lstat(line,&st) == 0) {
		if(S_ISREG(st.st_mode)) {
			int fd;
			md5_state_t md5_state;
			md5_init(&md5_state);
			char buffer[PATH_MAX];
			ssize_t size;
			char md5str[33];
			char modestr[11];

#ifdef O_NOATIME
			if((fd = open(line,O_RDONLY|O_NOATIME))==-1) {
#else
			if((fd = open(line,O_RDONLY))==-1) {
#endif

				conn_perror(cn, "WARNING open()");
				conn_printf(cn, "WARNING Can't open file: %s\n", line);
				return;
			}

			// Calcuate MD5
			{
				unsigned char md5bin[16];
				while((size = read(fd, buffer, sizeof buffer)))
					md5_append(&md5_state, (unsigned char*)buffer, size);
				md5_finish(&md5_state, (unsigned char*)md5bin);

				if(lseek(fd, SEEK_SET, 0)==-1) {
					conn_perror(cn, "ERROR lseek()");
					conn_abort(cn);
					return;
				}

				md5bin2str(md5bin, md5str);
			}

			mode2str(st.st_mode, modestr);
			conn_printf(cn, "PUT %ld %s %s %ld %ld %ld %s\n", 
				(long int)st.st_size,
				md5str,
				modestr,
				st.st_atime,
				st.st_ctime,
				st.st_mtime,
				line);
			while((size = read(fd, buffer, sizeof buffer))) 
				conn_write(cn, buffer, size);
			close(fd);
		}
		else if(S_ISDIR(st.st_mode)) {
			char modestr[11];
			mode2str(st.st_mode, modestr);
			conn_printf(cn, "MKDIR %s %ld %ld %ld %s\n",
				modestr,
				st.st_atime,
				st.st_ctime,
				st.st_mtime,
				line);
		}
		else if(S_ISLNK(st.st_mode)) {
			char buffer[PATH_MAX];
			conn_printf(cn, "SLNK %s\n", line);

			ssize_t l;
			if((l=readlink(line, buffer, sizeof buffer))==-1) {
				conn_perror(cn, "WARNING readlink()");
				return;
			}
			buffer[l] = '\0';
			conn_printf(cn, "%s\n", buffer);
		}
		else {
			conn_printf(cn, "WARNING Ignored %s\n", line);
		}
	}
}

static void proto_handle_put(conn_t* cn, const char* line) {
	const char* delim = " ";
	char* saveptr = NULL;
	char* token;
	char* ptr = (char*)line;
	int c = 0;

	ssize_t size = 0;
	mode_t mode = 0;
	time_t mtime = 0;
	time_t ctime = 0;
	time_t atime = 0;
	char* name = NULL;
	char* md5  = NULL;

	while((token = strtok_r(ptr, delim, &saveptr))) {
		switch(c) {
			case 0: size = atol(token); break;
			case 1: md5 = token; break;
			case 2: mode = str2mode(token); break;
			case 3: atime = atol(token); break; 
			case 4: ctime = atol(token); break;
			case 5: mtime = atol(token); break;
			case 6: name = token; break;
		}
		c++;
		ptr = NULL;
	}

	if(c != 7) {
		conn_printf(cn, "ERROR Protocol violation (%d)\n", __LINE__);
		conn_abort(cn);
		return ;
	}

	int fd = creat(name, O_CREAT|O_TRUNC);
	if(fd == -1) {
		conn_perror(cn, "WARNING creat()");
		return;
	}

	if(chmod(name,mode)==-1) {
		perror("WARNING chmod()");
	}

	struct utimbuf t;
	t.actime = atime;
	t.modtime = mtime;
	if(utime(name,&t)==-1) {
		perror("WARNING utime");
	}

	// CONTENT
	int bytes_left = size;
	int r;
	md5_state_t md5_state;
	unsigned char md5bin[16];
	char md5str[33];
	md5_init(&md5_state);
	while(!cn->abort && bytes_left) {
		if(cn->rbuf_len == 0) 
			(void)conn_read(cn);

		r = MIN(bytes_left, cn->rbuf_len);
		if(r) {
			write(fd, cn->rbuf, r);
			md5_append(&md5_state, (unsigned char*)cn->rbuf, r);
			conn_shift(cn,r);
			bytes_left -= r;
		}

		assert(bytes_left >= 0);
	}

	close(fd);
	md5_finish(&md5_state, (unsigned char*)md5bin);
	md5bin2str(md5bin, md5str);

	// Check md5
	if(strcmp(md5str,md5)!=0) {
		// Mismatch!
		conn_printf(cn, "WARNING %s md5-mismatch (%s <-> %s), removing file\n", 
			name,
			md5str, md5);
		if(unlink(name)==-1) {
			perror("WARNING: unlink()");
		}
	}
	else {
		struct utimbuf t;
		t.actime = atime;
		t.modtime = mtime;
		if(utime(name,&t)==-1) {
			perror("utime");
			conn_printf(cn, "WARNING Can't timestamp on directory: %s\n", name);
		}
		// md5 is fine
		conn_printf(cn, "GET %s\n", name);
	}
}

static void proto_handle_slnk(conn_t* cn, const char* line) {
	char curdir[PATH_MAX];

	// read next line to get target
	char target[PATH_MAX];
	if(!conn_readline(cn, target, sizeof target))
		return;

	getcwd(curdir, sizeof curdir);

	// Make sure it dosnt exist
	unlink(line);

	if(chdir(my_dirname(line))==-1) {
		conn_perror(cn, "WARNING chdir()");
		return;
	}

	if(symlink(target, my_basename(line))==-1) {
		conn_perror(cn, "ERROR symlink()");
		conn_abort(cn);
		return;
	}

	chdir(curdir);

	conn_printf(cn, "GET %s\n", line);
}
Ejemplo n.º 9
0
int my_copy(const char *from, const char *to, myf MyFlags)
{
  uint Count;
  int new_file_stat, create_flag;
  File from_file,to_file;
  char buff[IO_SIZE];
  struct stat stat_buff,new_stat_buff;
  DBUG_ENTER("my_copy");
  DBUG_PRINT("my",("from %s to %s MyFlags %d", from, to, MyFlags));

  from_file=to_file= -1;
  new_file_stat=0;
  if (MyFlags & MY_HOLD_ORIGINAL_MODES)		/* Copy stat if possible */
    new_file_stat=stat((char*) to, &new_stat_buff);

  if ((from_file=my_open(from,O_RDONLY | O_SHARE,MyFlags)) >= 0)
  {
    if (stat(from,&stat_buff))
    {
      my_errno=errno;
      goto err;
    }
    if (MyFlags & MY_HOLD_ORIGINAL_MODES && !new_file_stat)
      stat_buff=new_stat_buff;
    create_flag= (MyFlags & MY_DONT_OVERWRITE_FILE) ? O_EXCL : O_TRUNC;

    if ((to_file=  my_create(to,(int) stat_buff.st_mode,
			     O_WRONLY | create_flag | O_BINARY | O_SHARE,
			     MyFlags)) < 0)
      goto err;

    while ((Count=my_read(from_file,buff,IO_SIZE,MyFlags)) != 0)
	if (Count == (uint) -1 ||
	    my_write(to_file,buff,Count,MYF(MyFlags | MY_NABP)))
	goto err;

    if (my_close(from_file,MyFlags) | my_close(to_file,MyFlags))
      DBUG_RETURN(-1);				/* Error on close */

    /* Copy modes if possible */

    if (MyFlags & MY_HOLD_ORIGINAL_MODES && new_file_stat)
	DBUG_RETURN(0);			/* File copyed but not stat */
    VOID(chmod(to, stat_buff.st_mode & 07777)); /* Copy modes */
#if !defined(MSDOS) && !defined(__WIN__) && !defined(__EMX__) && !defined(OS2) && !defined(__NETWARE__)
    VOID(chown(to, stat_buff.st_uid,stat_buff.st_gid)); /* Copy ownership */
#endif
#if !defined(VMS) && !defined(__ZTC__)
    if (MyFlags & MY_COPYTIME)
    {
      struct utimbuf timep;
      timep.actime  = stat_buff.st_atime;
      timep.modtime = stat_buff.st_mtime;
      VOID(utime((char*) to, &timep)); /* last accessed and modified times */
    }
#endif
    DBUG_RETURN(0);
  }

err:
  if (from_file >= 0) VOID(my_close(from_file,MyFlags));
  if (to_file >= 0)   VOID(my_close(to_file,MyFlags));
  DBUG_RETURN(-1);
} /* my_copy */
Ejemplo n.º 10
0
static int wclique(int _n, int w[], unsigned char _a[], int sol[])
{     struct dsa _dsa, *dsa = &_dsa;
      int i, j, p, max_wt, max_nwt, wth, *used, *nwt, *pos;
      xlong_t timer;
      n = _n;
      wt = &w[1];
      a = _a;
      record = 0;
      rec_level = 0;
      rec = &sol[1];
      clique = xcalloc(n, sizeof(int));
      set = xcalloc(n, sizeof(int));
      used = xcalloc(n, sizeof(int));
      nwt = xcalloc(n, sizeof(int));
      pos = xcalloc(n, sizeof(int));
      /* start timer */
      timer = xtime();
      /* order vertices */
      for (i = 0; i < n; i++)
      {  nwt[i] = 0;
         for (j = 0; j < n; j++)
            if (is_edge(dsa, i, j)) nwt[i] += wt[j];
      }
      for (i = 0; i < n; i++)
         used[i] = 0;
      for (i = n-1; i >= 0; i--)
      {  max_wt = -1;
         max_nwt = -1;
         for (j = 0; j < n; j++)
         {  if ((!used[j]) && ((wt[j] > max_wt) || (wt[j] == max_wt
               && nwt[j] > max_nwt)))
            {  max_wt = wt[j];
               max_nwt = nwt[j];
               p = j;
            }
         }
         pos[i] = p;
         used[p] = 1;
         for (j = 0; j < n; j++)
            if ((!used[j]) && (j != p) && (is_edge(dsa, p, j)))
               nwt[j] -= wt[p];
      }
      /* main routine */
      wth = 0;
      for (i = 0; i < n; i++)
      {  wth += wt[pos[i]];
         sub(dsa, i, pos, 0, 0, wth);
         clique[pos[i]] = record;
#if 0
         if (utime() >= timer + 5.0)
#else
         if (xdifftime(xtime(), timer) >= 5.0 - 0.001)
#endif
         {  /* print current record and reset timer */
            xprintf("level = %d (%d); best = %d\n", i+1, n, record);
#if 0
            timer = utime();
#else
            timer = xtime();
#endif
         }
      }
      xfree(clique);
      xfree(set);
      xfree(used);
      xfree(nwt);
      xfree(pos);
      /* return the solution found */
      for (i = 1; i <= rec_level; i++) sol[i]++;
      return rec_level;
}
Ejemplo n.º 11
0
static void * worker_thread_handler(void * x) {
    WorkerThread * wt = (WorkerThread *)x;

    for (;;) {
        AsyncReqInfo * req = wt->req;

        assert(req != NULL);
        req->error = 0;
        switch(req->type) {
        case AsyncReqTimer:
#if defined(_WIN32) && !defined(__CYGWIN__)
            Sleep(EVENTS_TIMER_RESOLUTION);
            events_timer_ms = GetTickCount();
#else
            {
                struct timespec timenow;
                usleep(EVENTS_TIMER_RESOLUTION * 1000);
                if (clock_gettime(CLOCK_REALTIME, &timenow) == 0) {
                    events_timer_ms = (uint32_t)(timenow.tv_nsec / 1000000 + timenow.tv_sec * 1000);
                }
            }
#endif
            break;

        case AsyncReqRead:              /* File read */
            req->u.fio.rval = read(req->u.fio.fd, req->u.fio.bufp, req->u.fio.bufsz);
            if (req->u.fio.rval == -1) {
                req->error = errno;
                assert(req->error);
            }
            break;

        case AsyncReqWrite:             /* File write */
            req->u.fio.rval = write(req->u.fio.fd, req->u.fio.bufp, req->u.fio.bufsz);
            if (req->u.fio.rval == -1) {
                req->error = errno;
                assert(req->error);
            }
            break;

        case AsyncReqSeekRead:          /* File read at offset */
            req->u.fio.rval = pread(req->u.fio.fd, req->u.fio.bufp, req->u.fio.bufsz, (off_t)req->u.fio.offset);
            if (req->u.fio.rval == -1) {
                req->error = errno;
                assert(req->error);
            }
            break;

        case AsyncReqSeekWrite:         /* File write at offset */
            req->u.fio.rval = pwrite(req->u.fio.fd, req->u.fio.bufp, req->u.fio.bufsz, (off_t)req->u.fio.offset);
            if (req->u.fio.rval == -1) {
                req->error = errno;
                assert(req->error);
            }
            break;

        case AsyncReqRecv:              /* Socket recv */
            req->u.sio.rval = recv(req->u.sio.sock, req->u.sio.bufp, req->u.sio.bufsz, req->u.sio.flags);
            if (req->u.sio.rval == -1) {
                req->error = errno;
                assert(req->error);
            }
            break;

        case AsyncReqSend:              /* Socket send */
            req->u.sio.rval = send(req->u.sio.sock, req->u.sio.bufp, req->u.sio.bufsz, req->u.sio.flags);
            if (req->u.sio.rval == -1) {
                req->error = errno;
                assert(req->error);
            }
            break;

        case AsyncReqRecvFrom:          /* Socket recvfrom */
            req->u.sio.rval = recvfrom(req->u.sio.sock, req->u.sio.bufp, req->u.sio.bufsz, req->u.sio.flags, req->u.sio.addr, &req->u.sio.addrlen);
            if (req->u.sio.rval == -1) {
                req->error = errno;
                trace(LOG_ASYNCREQ, "AsyncReqRecvFrom: req %p, type %d, error %d", req, req->type, req->error);
                assert(req->error);
            }
            break;

        case AsyncReqSendTo:            /* Socket sendto */
            req->u.sio.rval = sendto(req->u.sio.sock, req->u.sio.bufp, req->u.sio.bufsz, req->u.sio.flags, req->u.sio.addr, req->u.sio.addrlen);
            if (req->u.sio.rval == -1) {
                req->error = errno;
                assert(req->error);
            }
            break;

        case AsyncReqAccept:            /* Accept socket connections */
            req->u.acc.rval = accept(req->u.acc.sock, req->u.acc.addr, req->u.acc.addr ? &req->u.acc.addrlen : NULL);
            if (req->u.acc.rval == -1) {
                req->error = errno;
                trace(LOG_ASYNCREQ, "AsyncReqAccept: req %p, type %d, error %d", req, req->type, req->error);
                assert(req->error);
            }
            break;

        case AsyncReqConnect:           /* Connect to socket */
            req->u.con.rval = connect(req->u.con.sock, req->u.con.addr, req->u.con.addrlen);
            if (req->u.con.rval == -1) {
                req->error = errno;
                trace(LOG_ASYNCREQ, "AsyncReqConnect: req %p, type %d, error %d", req, req->type, req->error);
                assert(req->error);
            }
            break;

/* Platform dependant IO methods */
#if defined(_WIN32) || defined(__CYGWIN__)
        case AsyncReqConnectPipe:
            req->u.cnp.rval = ConnectNamedPipe(req->u.cnp.pipe, NULL);
            if (!req->u.cnp.rval) {
                req->error = set_win32_errno(GetLastError());
                assert(req->error);
            }
            break;
#elif defined(_WRS_KERNEL)
#else
        case AsyncReqWaitpid:           /* Wait for process change */
            req->u.wpid.rval = waitpid(req->u.wpid.pid, &req->u.wpid.status, req->u.wpid.options);
            if (req->u.wpid.rval == -1) {
                req->error = errno;
                assert(req->error);
            }
            break;
#endif

        case AsyncReqSelect:
            {
                struct timeval tv;
                tv.tv_sec = (long)req->u.select.timeout.tv_sec;
                tv.tv_usec = req->u.select.timeout.tv_nsec / 1000;
                req->u.select.rval = select(req->u.select.nfds, &req->u.select.readfds,
                            &req->u.select.writefds, &req->u.select.errorfds, &tv);
                if (req->u.select.rval == -1) {
                    req->error = errno;
                    assert(req->error);
                }
            }
            break;

        case AsyncReqClose:
            req->u.fio.rval = close(req->u.fio.fd);
            if (req->u.fio.rval == -1) {
                req->error = errno;
                assert(req->error);
            }
            break;

        case AsyncReqCloseDir:
            req->u.dio.rval = closedir((DIR *)req->u.dio.dir);
            if (req->u.dio.rval == -1) {
                req->error = errno;
                assert(req->error);
            }
            break;

        case AsyncReqOpen:
            req->u.fio.rval = open(req->u.fio.file_name, req->u.fio.flags, req->u.fio.permission);
            if (req->u.fio.rval == -1) {
                req->error = errno;
                assert(req->error);
            }
            break;

        case AsyncReqOpenDir:
            req->u.dio.dir = opendir(req->u.dio.path);
            if (req->u.dio.dir == NULL) {
                req->error = errno;
                assert(req->error);
            }
            break;

        case AsyncReqFstat:
            memset(&req->u.fio.statbuf, 0, sizeof(req->u.fio.statbuf));
            req->u.fio.rval = fstat(req->u.fio.fd, &req->u.fio.statbuf);
            if (req->u.fio.rval == -1) {
                req->error = errno;
                assert(req->error);
            }
#if defined(_WIN32) || defined(__CYGWIN__)
            req->u.fio.win32_attrs = req->error || !req->u.fio.file_name ?
                INVALID_FILE_ATTRIBUTES : GetFileAttributes(req->u.fio.file_name);
#endif
            break;

        case AsyncReqStat:
            memset(&req->u.fio.statbuf, 0, sizeof(req->u.fio.statbuf));
            req->u.fio.rval = stat(req->u.fio.file_name, &req->u.fio.statbuf);
            if (req->u.fio.rval == -1) {
                req->error = errno;
                assert(req->error);
            }
#if defined(_WIN32) || defined(__CYGWIN__)
            req->u.fio.win32_attrs = req->error ?
                INVALID_FILE_ATTRIBUTES : GetFileAttributes(req->u.fio.file_name);
#endif
            break;

        case AsyncReqLstat:
            memset(&req->u.fio.statbuf, 0, sizeof(req->u.fio.statbuf));
            req->u.fio.rval = lstat(req->u.fio.file_name, &req->u.fio.statbuf);
            if (req->u.fio.rval == -1) {
                req->error = errno;
                assert(req->error);
            }
#if defined(_WIN32) || defined(__CYGWIN__)
            req->u.fio.win32_attrs = req->error ?
                INVALID_FILE_ATTRIBUTES : GetFileAttributes(req->u.fio.file_name);
#endif
            break;

        case AsyncReqSetStat:
            {
                int err = 0;
                if (req->u.fio.set_stat_flags & AsyncReqSetSize) {
                    if (truncate(req->u.fio.file_name, (off_t)req->u.fio.statbuf.st_size) < 0) err = errno;
                }
                if (req->u.fio.set_stat_flags & AsyncReqSetPermissions) {
                    if (chmod(req->u.fio.file_name, req->u.fio.statbuf.st_mode) < 0) err = errno;
                }
#if defined(_WIN32) || defined(__CYGWIN__) || defined(_WRS_KERNEL)
#  if defined(_WIN32) || defined(__CYGWIN__)
                if (req->u.fio.win32_attrs != INVALID_FILE_ATTRIBUTES) {
                    if (SetFileAttributes(req->u.fio.file_name, req->u.fio.win32_attrs) == 0)
                        err = set_win32_errno(GetLastError());
                }
#  endif
#else
                if (req->u.fio.set_stat_flags & AsyncReqSetUidGid) {
                    if (chown(req->u.fio.file_name, req->u.fio.statbuf.st_uid, req->u.fio.statbuf.st_gid) < 0) err = errno;
                }
#endif
                if (req->u.fio.set_stat_flags & AsyncReqSetAcModTime) {
                    struct utimbuf buf;
                    buf.actime = req->u.fio.statbuf.st_atime;
                    buf.modtime = req->u.fio.statbuf.st_mtime;
                    if (utime(req->u.fio.file_name, &buf) < 0) err = errno;
                }
                req->error = err;
            }
            break;

        case AsyncReqFSetStat:
            {
                int err = 0;
                if (req->u.fio.set_stat_flags & AsyncReqSetSize) {
                    if (ftruncate(req->u.fio.fd, (off_t)req->u.fio.statbuf.st_size) < 0) err = errno;
                }
#if defined(_WIN32) || defined(__CYGWIN__) || defined(_WRS_KERNEL)
                if (req->u.fio.set_stat_flags & AsyncReqSetPermissions) {
                    if (chmod(req->u.fio.file_name, req->u.fio.statbuf.st_mode) < 0) err = errno;
                }
#  if defined(_WIN32) || defined(__CYGWIN__)
                if (req->u.fio.win32_attrs != INVALID_FILE_ATTRIBUTES) {
                    if (SetFileAttributes(req->u.fio.file_name, req->u.fio.win32_attrs) == 0)
                        err = set_win32_errno(GetLastError());
                }
#  endif
#else
                if (req->u.fio.set_stat_flags & AsyncReqSetUidGid) {
                    if (fchown(req->u.fio.fd, req->u.fio.statbuf.st_uid, req->u.fio.statbuf.st_gid) < 0) err = errno;
                }
                if (req->u.fio.set_stat_flags & AsyncReqSetPermissions) {
                    if (fchmod(req->u.fio.fd, req->u.fio.statbuf.st_mode) < 0) err = errno;
                }
#endif
                if (req->u.fio.set_stat_flags & AsyncReqSetAcModTime) {
                    struct utimbuf buf;
                    buf.actime = req->u.fio.statbuf.st_atime;
                    buf.modtime = req->u.fio.statbuf.st_mtime;
#if defined(_WIN32) && !defined(__MINGW32__)
                    if (futime(req->u.fio.fd, &buf) < 0) err = errno;
#else
                    if (utime(req->u.fio.file_name, &buf) < 0) err = errno;
#endif
                }
                req->error = err;
            }
            break;

        case AsyncReqRemove:
            req->u.fio.rval = remove(req->u.fio.file_name);
            if (req->u.fio.rval == -1) {
                req->error = errno;
                assert(req->error);
            }
            break;

        case AsyncReqReadDir:
            {
                int cnt = 0;
                while (cnt < req->u.dio.max_files) {
                    char path[FILE_PATH_SIZE];
                    struct DirFileNode * file = req->u.dio.files + cnt;
                    struct dirent * e;
                    struct stat st;
                    errno = 0;
                    e = readdir((DIR *)req->u.dio.dir);
                    if (e == NULL) {
                        req->error = errno;
                        if (req->error == 0) req->u.dio.eof = 1;
                        break;
                    }
                    if (strcmp(e->d_name, ".") == 0) continue;
                    if (strcmp(e->d_name, "..") == 0) continue;
                    file->path = loc_strdup(e->d_name);
                    memset(&st, 0, sizeof(st));
                    snprintf(path, sizeof(path), "%s/%s", req->u.dio.path, e->d_name);
                    if (stat(path, &st) == 0) {
#if defined(_WIN32) || defined(__CYGWIN__)
                        file->win32_attrs =  GetFileAttributes(path);
#endif
                        file->statbuf = (struct stat *)loc_alloc(sizeof(struct stat));
                        memcpy(file->statbuf, &st, sizeof(struct stat));
                    }
                    cnt++;
                }
            }
            break;

        case AsyncReqRoots:
            {
                struct stat st;
                struct RootDevNode * newDevNode = NULL;

#if defined(_WIN32) || defined(__CYGWIN__)
                {
                    struct RootDevNode * curDevNode = NULL;
                    int disk = 0;
                    DWORD disks = GetLogicalDrives();
                    for (disk = 0; disk <= 30; disk++) {
                        if (disks & (1 << disk)) {
                            char path[32];
                            newDevNode = (struct RootDevNode *)loc_alloc_zero(sizeof(struct RootDevNode));
                            if (curDevNode == NULL) req->u.root.lst = newDevNode;
                            else curDevNode->next = newDevNode;
                            curDevNode = newDevNode;
                            snprintf(path, sizeof(path), "%c:\\", 'A' + disk);
                            newDevNode->devname = loc_strdup(path);
                            if (disk >= 2) {
                                ULARGE_INTEGER total_number_of_bytes;
                                BOOL has_size = GetDiskFreeSpaceExA(path, NULL, &total_number_of_bytes, NULL);
                                memset(&st, 0, sizeof(st));
#if defined(__CYGWIN__)
                                snprintf(path, sizeof(path), "/cygdrive/%c", 'a' + disk);
#endif
                                if (has_size && stat(path, &st) == 0) {
                                    newDevNode->win32_attrs =  GetFileAttributes(path);
                                    newDevNode->statbuf = (struct stat *)loc_alloc_zero(sizeof(struct stat));
                                    memcpy(newDevNode->statbuf, &st, sizeof(struct stat));
                                }
                            }
                        }
                    }
                }
#elif defined(_WRS_KERNEL)
                {
                    struct RootDevNode * curDevNode = NULL;
                    extern DL_LIST iosDvList;
                    DEV_HDR * dev;
                    for (dev = (DEV_HDR *)DLL_FIRST(&iosDvList); dev != NULL; dev = (DEV_HDR *)DLL_NEXT(&dev->node)) {
                        char path[FILE_PATH_SIZE];
                        if (strcmp(dev->name, "host:") == 0) {
                            /* Windows host is special case */
                            int d;
                            for (d = 'a'; d < 'z'; d++) {
                                snprintf(path, sizeof(path), "%s%c:/", dev->name, d);
                                if (stat(path, &st) == 0 && S_ISDIR(st.st_mode)) {
                                    newDevNode = (struct RootDevNode *)loc_alloc_zero(sizeof(struct RootDevNode));
                                    if (curDevNode == NULL) req->u.root.lst = newDevNode;
                                    else curDevNode->next = newDevNode;
                                    curDevNode = newDevNode;

                                    newDevNode->devname = loc_strdup(path);
                                    newDevNode->statbuf = (struct stat *)loc_alloc_zero(sizeof(struct stat));
                                    memcpy(newDevNode->statbuf, &st, sizeof(struct stat));
                                }
                            }
                        }
                        snprintf(path, sizeof(path), "%s/", dev->name);
                        if (stat(path, &st) == 0 && S_ISDIR(st.st_mode)) {
                            newDevNode = (struct RootDevNode *)loc_alloc_zero(sizeof(struct RootDevNode));
                            if (curDevNode == NULL) req->u.root.lst = newDevNode;
                            else curDevNode->next = newDevNode;
                            curDevNode = newDevNode;

                            newDevNode->devname = loc_strdup(path);
                            newDevNode->statbuf = (struct stat *)loc_alloc_zero(sizeof(struct stat));
                            memcpy(newDevNode->statbuf, &st, sizeof(struct stat));
                        }
                    }
                }
#else
                req->u.root.lst = newDevNode = (struct RootDevNode *)loc_alloc_zero(sizeof(struct RootDevNode));
                newDevNode->devname = loc_strdup("/");
                if (stat("/", &st) == 0) {
                    newDevNode->statbuf = (struct stat *)loc_alloc_zero(sizeof(struct stat));
                    memcpy(newDevNode->statbuf, &st, sizeof(struct stat));
                }
#endif
            }
            break;

        case AsyncReqUser:              /* User defined request */
            req->u.user.rval = req->u.user.func(req->u.user.data);
            if (req->u.user.rval == -1) {
                req->error = errno;
                assert(req->error);
            }
            break;

        default:
            req->error = ENOSYS;
            break;
        }
        if (req->type == AsyncReqTimer) {
            if (async_shutdown.state == SHUTDOWN_STATE_PENDING) break;
            continue;
        }
        trace(LOG_ASYNCREQ, "async_req_complete: req %p, type %d, error %d", req, req->type, req->error);
        check_error(pthread_mutex_lock(&wtlock));
        /* Post event inside lock to make sure a new worker thread is not created unnecessarily */
        post_event(req->done, req);
        wt->req = NULL;
        if (wtlist_size >= MAX_WORKER_THREADS || async_shutdown.state == SHUTDOWN_STATE_PENDING) {
            check_error(pthread_mutex_unlock(&wtlock));
            break;
        }
        list_add_last(&wt->wtlink, &wtlist);
        wtlist_size++;
        for (;;) {
            check_error(pthread_cond_wait(&wt->cond, &wtlock));
            if (wt->req != NULL) break;
        }
        check_error(pthread_mutex_unlock(&wtlock));
        if (wt->req == &shutdown_req) break;
    }
    post_event(worker_thread_exit, wt);
    return NULL;
}
Ejemplo n.º 12
0
static void
copyfile( char *name, char *toname, mode_t mode, char *group, char *owner,
          int dotimes, uid_t uid, gid_t gid )
{
  int fromfd, tofd, cc, wc, exists;
  char buf[BUFSIZ], *bp;
  struct stat sb, tosb;
  struct utimbuf utb;

  exists = (lstat(toname, &tosb) == 0);

  fromfd = open(name, O_RDONLY);
  if (fromfd < 0 || fstat(fromfd, &sb) < 0)
    fail("cannot access %s", name);
  if (exists && (!S_ISREG(tosb.st_mode) || access(toname, W_OK) < 0))
    (void) (S_ISDIR(tosb.st_mode) ? rmdir : unlink)(toname);
  tofd = open(toname, O_CREAT | O_WRONLY, 0666);
  if (tofd < 0)
    fail("cannot create %s", toname);

  bp = buf;
  while ((cc = read(fromfd, bp, sizeof buf)) > 0)
  {
    while ((wc = write(tofd, bp, (unsigned int)cc)) > 0)
    {
      if ((cc -= wc) == 0)
        break;
      bp += wc;
    }
    if (wc < 0)
      fail("cannot write to %s", toname);
  }
  if (cc < 0)
    fail("cannot read from %s", name);

  if (ftruncate(tofd, sb.st_size) < 0)
    fail("cannot truncate %s", toname);
#if !defined(VMS)
  if (dotimes)
  {
    utb.actime = sb.st_atime;
    utb.modtime = sb.st_mtime;
    if (utime(toname, &utb) < 0)
      fail("cannot set times of %s", toname);
  }
#ifdef HAVE_FCHMOD
  if (fchmod(tofd, mode) < 0)
#else
  if (chmod(toname, mode) < 0)
#endif
    fail("cannot change mode of %s", toname);
#endif
  if ((owner || group) && fchown(tofd, uid, gid) < 0)
    fail("cannot change owner of %s", toname);

  /* Must check for delayed (NFS) write errors on close. */
  if (close(tofd) < 0)
    fail("cannot write to %s", toname);
  close(fromfd);
#if defined(VMS)
  if (chmod(toname, (mode & (S_IREAD | S_IWRITE))) < 0)
    fail("cannot change mode of %s", toname);
  if (dotimes)
  {
    utb.actime = sb.st_atime;
    utb.modtime = sb.st_mtime;
    if (utime(toname, &utb) < 0)
      fail("cannot set times of %s", toname);
  }
#endif
}
Ejemplo n.º 13
0
/*
 * incremental: incremental update
 *
 *	i)	dbpath	dbpath directory
 *	i)	root	root directory of source tree
 *	r)		0: not updated, 1: updated
 */
int
incremental(const char *dbpath, const char *root)
{
	STATISTICS_TIME *tim;
	struct stat statp;
	STRBUF *addlist = strbuf_open(0);
	STRBUF *deletelist = strbuf_open(0);
	STRBUF *addlist_other = strbuf_open(0);
	IDSET *deleteset, *findset;
	int updated = 0;
	const char *path;
	unsigned int id, limit;

	tim = statistics_time_start("Time of inspecting %s and %s.", dbname(GTAGS), dbname(GRTAGS));
	if (vflag) {
		fprintf(stderr, " Tag found in '%s'.\n", dbpath);
		fprintf(stderr, " Incremental updating.\n");
	}
	/*
	 * get modified time of GTAGS.
	 */
	path = makepath(dbpath, dbname(GTAGS), NULL);

	if (gpath_open(dbpath, 0) < 0)
		die("GPATH not found.");
	/*
	 * deleteset:
	 *	The list of the path name which should be deleted from GPATH.
	 * findset:
	 *	The list of the path name which exists in the current project.
	 *	A project is limited by the --file option.
	 */
	deleteset = idset_open(gpath_nextkey());
	findset = idset_open(gpath_nextkey());
	total = 0;
	/*
	 * Make add list and delete list for update.
	 */
	if (single_update) {
		int type;
		const char *fid = gpath_path2fid(single_update, &type);
		/*
		 * The --single-update=file supports only updating.
		 * If it is new file, this option is ignored, and the processing is
		 * automatically switched to the normal procedure.
		 */
		if (fid == NULL) {
			if (vflag)
				fprintf(stderr, " --single-update option ignored, because '%s' is new file.\n", single_update);
			goto normal_update;
		}
		/*
		 * If type != GPATH_SOURCE then we have nothing to do, and you will see
		 * a message 'Global databases are up to date.'.
		 */
		if (type == GPATH_SOURCE) {
			strbuf_puts0(addlist, single_update);
			idset_add(deleteset, atoi(fid));
			total++;
		}
	} else {
normal_update:
		if (file_list)
			find_open_filelist(file_list, root);
		else
			find_open(NULL);
		while ((path = find_read()) != NULL) {
			const char *fid;
			int n_fid = 0;
			int other = 0;

			/* a blank at the head of path means 'NOT SOURCE'. */
			if (*path == ' ') {
				if (test("b", ++path))
					continue;
				other = 1;
			}
			if (stat(path, &statp) < 0)
				die("stat failed '%s'.", path);
			fid = gpath_path2fid(path, NULL);
			if (fid) { 
				n_fid = atoi(fid);
				idset_add(findset, n_fid);
			}
			if (other) {
				if (fid == NULL)
					strbuf_puts0(addlist_other, path);
			} else {
				if (fid == NULL) {
					strbuf_puts0(addlist, path);
					total++;
				} else if (gpath_mtime(NULL, fid) < statp.st_mtime) {
					if (uflag) {
						printf("%s\n", path);
					} else {
						strbuf_puts0(addlist, path);
						total++;
						idset_add(deleteset, n_fid);
					}
				}
			}
		}
		find_close();
		/*
		 * make delete list.
		 */
		if (remove_lost) {
			limit = gpath_nextkey();
		} else {
			limit = 0;
		}
		for (id = 1; id < limit; id++) {
			char fid[MAXFIDLEN];
			int type;

			snprintf(fid, sizeof(fid), "%d", id);
			/*
			 * This is a hole of GPATH. The hole increases if the deletion
			 * and the addition are repeated.
			 */
			if ((path = gpath_fid2path(fid, &type)) == NULL)
				continue;
			/*
			 * The file which does not exist in the findset is treated
			 * assuming that it does not exist in the file system.
			 */
			if (type == GPATH_OTHER) {
				if (!idset_contains(findset, id) || !test("f", path) || test("b", path))
					strbuf_puts0(deletelist, path);
			} else {
				if (!idset_contains(findset, id) || !test("f", path)) {
					strbuf_puts0(deletelist, path);
					idset_add(deleteset, id);
				}
			}
		}
	}
	gpath_close();
	statistics_time_end(tim);
	/*
	 * execute updating.
	 */
	if ((!idset_empty(deleteset) || strbuf_getlen(addlist) > 0) ||
	    (strbuf_getlen(deletelist) + strbuf_getlen(addlist_other) > 0))
	{
		int db;

		updated = 1;
		tim = statistics_time_start("Time of updating %s and %s.", dbname(GTAGS), dbname(GRTAGS));
		if (!idset_empty(deleteset) || strbuf_getlen(addlist) > 0)
			updatetags(dbpath, root, deleteset, addlist);
		if (strbuf_getlen(deletelist) + strbuf_getlen(addlist_other) > 0) {
			const char *start, *end, *p;

			if (vflag)
				fprintf(stderr, "[%s] Updating '%s'.\n", now(), dbname(GPATH));
			gpath_open(dbpath, 2);
			if (strbuf_getlen(deletelist) > 0) {
				start = strbuf_value(deletelist);
				end = start + strbuf_getlen(deletelist);

				for (p = start; p < end; p += strlen(p) + 1)
					gpath_delete(p);
			}
			if (strbuf_getlen(addlist_other) > 0) {
				start = strbuf_value(addlist_other);
				end = start + strbuf_getlen(addlist_other);

				for (p = start; p < end; p += strlen(p) + 1)
					gpath_put(p, GPATH_OTHER);
			}
			gpath_close();
		}
		/*
		 * Update modification time of tag files
		 * because they may have no definitions.
		 */
		for (db = GTAGS; db < GTAGLIM; db++)
			utime(makepath(dbpath, dbname(db), NULL), NULL);
		statistics_time_end(tim);
	}
	if (vflag) {
		if (updated)
			fprintf(stderr, " Global databases have been modified.\n");
		else
			fprintf(stderr, " Global databases are up to date.\n");
		fprintf(stderr, "[%s] Done.\n", now());
	}
	strbuf_close(addlist);
	strbuf_close(deletelist);
	strbuf_close(addlist_other);
	idset_close(deleteset);
	idset_close(findset);

	return updated;
}
Ejemplo n.º 14
0
int
cppath(int a_ctrl, char *a_srcPath, char *a_dstPath, mode_t a_mode)
{
	char		*linknam = (char *)NULL;
	int		dstFd;
	int		len;
	int		srcFd;
	long		status;
	struct stat	srcStatbuf;
	struct utimbuf	times;

	/* entry debugging info */

	echoDebug(DBG_CPPATH_ENTRY, a_ctrl, a_mode, a_srcPath, a_dstPath);

	/* open source file for reading */

	srcFd = open(a_srcPath, O_RDONLY);
	if (srcFd < 0) {
		progerr(ERR_OPEN_READ, a_srcPath,
				errno, strerror(errno));
		return (1);
	}

	/* obtain file status of source file */

	if (fstat(srcFd, &srcStatbuf) != 0) {
		progerr(ERR_FSTAT, srcFd, a_srcPath, errno, strerror(errno));
		(void) close(srcFd);
		return (1);
	}

	/*
	 * Determine the permissions mode for the destination:
	 * - if MODE_SET is specified:
	 * --> use a_mode (do not mask off any portion)
	 * --> If a_mode is unknown (? in the pkgmap), then the file gets
	 * --> installed with the default 0644 mode
	 * - if MODE_SRC is specified:
	 * --> use the mode of the source (srcStatbuf.st_mode) but mask off all
	 * --> non-access mode bits (remove SET?UID bits)
	 * - otherwise:
	 * --> use 0666
	 */

	if (a_ctrl & MODE_SET) {
		mode_t	usemode;

		usemode = (a_mode ^ BADMODE) ? a_mode : 0644;
		if (a_mode != usemode && usemode == 0644) {
			logerr(WRN_DEF_MODE, a_dstPath);
			a_mode = usemode;
		}
	} else if (a_ctrl & MODE_SRC) {
		a_mode = (srcStatbuf.st_mode & S_IAMB);
	} else {
		a_mode = 0666;
	}

	/*
	 * Get fd of newly created destination file or, if this
	 * is an overwrite,  a temporary file (linknam).
	 */

	dstFd = write_file(&linknam, a_ctrl, a_mode, a_dstPath);
	if (dstFd < 0) {
		(void) close(srcFd);
		return (1);
	}

	/*
	 * source and target files are open: copy data
	 */

	status = copyFile(srcFd, dstFd, a_srcPath, a_dstPath, &srcStatbuf, 0);

	(void) close(srcFd);
	(void) close(dstFd);

	if (status != 0) {
		progerr(ERR_INPUT, a_srcPath, errno, strerror(errno));
		if (linknam) {
			(void) remove(linknam);
		}
		return (1);
	}

	/*
	 * If this is an overwrite, rename temp over original
	 */

	if ((linknam != (char *)NULL) && (rename(linknam, a_dstPath) != 0)) {
		FILE	*logfp = (FILE *)NULL;
		char	busylog[PATH_MAX];

		/* output log message if busy else program error */

		if (errno == ETXTBSY) {
			logerr(MSG_PROCMV, linknam);
		} else {
			progerr(ERR_OUTPUT_WRITING, a_dstPath, errno,
				strerror(errno));
		}

		(void) remove(linknam);

		/* open the log file and append log entry */

		len = snprintf(busylog, sizeof (busylog),
				"%s/textbusy", get_PKGADM());
		if (len > sizeof (busylog)) {
			progerr(ERR_CREATE_PATH_2, get_PKGADM(),
				"textbusy");
		} else {
			logfp = fopen(busylog, "a");
			if (logfp == NULL) {
				progerr(ERR_LOG, busylog, errno,
					strerror(errno));
			} else {
				(void) fprintf(logfp, "%s\n", linknam);
				(void) fclose(logfp);
			}
		}
	}

	/* set access/modification times for target */

	times.actime = srcStatbuf.st_atime;
	times.modtime = srcStatbuf.st_mtime;

	if (utime(a_dstPath, &times) != 0) {
		progerr(ERR_MODTIM, a_dstPath, errno, strerror(errno));
		return (1);
	}

	/* success! */

	return (0);
}
Ejemplo n.º 15
0
int sim_make_ROM_include(const char *rom_filename,
                         int expected_size,
                         unsigned int expected_checksum,
                         const char *include_filename, 
                         const char *rom_array_name,
                         const char *Comments)
{
FILE *rFile;
FILE *iFile;
time_t now;
int bytes_written = 0;
int include_bytes;
int c;
struct stat statb;
const char *load_filename;
unsigned char *ROMData = NULL;
unsigned char *include_ROMData = NULL;
char *include_array_name = NULL;
unsigned int checksum = 0;
unsigned int include_checksum;
int defines_found;

if (NULL == (rFile = fopen (rom_filename, "rb"))) {
    printf ("Error Opening ROM binary file '%s' for input: %s\n", rom_filename, strerror(errno));
    if (0 != sim_read_ROM_include(include_filename, 
                                  &include_bytes,
                                  &include_ROMData,
                                  &include_checksum,
                                  &include_array_name,
                                  &defines_found))
        return -1;
    c = ((include_checksum == expected_checksum) && 
         (include_bytes == expected_size) &&
         (0 == strcmp(include_array_name, rom_array_name)) &&
         defines_found);
    free(include_ROMData);
    free(include_array_name);
    if (!c)
        printf ("Existing ROM include file: %s has unexpected content\n", include_filename);
    else
        printf ("Existing ROM include file: %s looks good\n", include_filename);
    return (c ? 0 : -1);
    }
if (stat (rom_filename, &statb)) {
    printf ("Error stating '%s': %s\n", rom_filename, strerror(errno));
    fclose (rFile);
    return -1;
    }
if (statb.st_size != expected_size) {
    printf ("Error: ROM file '%s' has an unexpected size: %d vs %d\n", rom_filename, (int)statb.st_size, expected_size);
    printf ("This can happen if the file was transferred or unpacked incorrectly\n");
    printf ("and in the process tried to convert line endings rather than passing\n");
    printf ("the file's contents unmodified\n");
    fclose (rFile);
    return -1;
    }
ROMData = (unsigned char *)malloc (statb.st_size);
if ((size_t)(statb.st_size) != fread (ROMData, sizeof(*ROMData), statb.st_size, rFile)) {
    printf ("Error reading '%s': %s\n", rom_filename, strerror(errno));
    fclose (rFile);
    free (ROMData);
    return -1;
    }
fclose (rFile);
for (c=0; c<statb.st_size; ++c)
    checksum += ROMData[c];
checksum = ~checksum;
if ((expected_checksum != 0) && (checksum != expected_checksum)) {
    printf ("Error: ROM file '%s' has an unexpected checksum: 0x%08X vs 0x%08X\n", rom_filename, checksum, expected_checksum);
    printf ("This can happen if the file was transferred or unpacked incorrectly\n");
    printf ("and in the process tried to convert line endings rather than passing\n");
    printf ("the file's contents unmodified\n");
    free (ROMData);
    return -1;
    }
/*
 * If the target include file already exists, determine if it contains the exact
 * data in the base ROM image.  If so, then we are already done
 */
if (0 == sim_read_ROM_include(include_filename, 
                              &include_bytes,
                              &include_ROMData,
                              &include_checksum,
                              &include_array_name,
                              &defines_found)) {
    c = ((include_checksum == expected_checksum) && 
         (include_bytes == expected_size) &&
         (0 == strcmp (include_array_name, rom_array_name)) &&
         (0 == memcmp (include_ROMData, ROMData, include_bytes)) &&
         defines_found);
    free(include_ROMData);
    free(include_array_name);
    if (c) {
        free (ROMData);
        return 0;
        }
    }

if (NULL == (iFile = fopen (include_filename, "w"))) {
    printf ("Error Opening '%s' for output: %s\n", include_filename, strerror(errno));
    free (ROMData);
    return -1;
    }
load_filename = strrchr (rom_filename, '/');
if (load_filename)
    ++load_filename;
else
    load_filename = rom_filename;
time (&now);
fprintf (iFile, "#ifndef ROM_%s_H\n", rom_array_name);
fprintf (iFile, "#define ROM_%s_H 0\n", rom_array_name);
fprintf (iFile, "/*\n");
fprintf (iFile, "   %s         produced at %s", include_filename, ctime(&now));
fprintf (iFile, "   from %s which was last modified at %s", rom_filename, ctime(&statb.st_mtime));
fprintf (iFile, "   file size: %d (0x%X) - checksum: 0x%08X\n", (int)statb.st_size, (int)statb.st_size, checksum);
fprintf (iFile, "   This file is a generated file and should NOT be edited or changed by hand.\n");
if (Comments)
    fprintf (iFile, "\n   %s\n\n", Comments);
fprintf (iFile, "*/\n");
fprintf (iFile, "#define BOOT_CODE_SIZE 0x%X\n", (int)statb.st_size);
fprintf (iFile, "#define BOOT_CODE_FILENAME \"%s\"\n", load_filename);
fprintf (iFile, "#define BOOT_CODE_ARRAY %s\n", rom_array_name);
fprintf (iFile, "unsigned char %s[] = {", rom_array_name);
for (bytes_written=0;bytes_written<statb.st_size; ++bytes_written) {
    c = ROMData[bytes_written];
    if (0 == bytes_written%16)
        fprintf (iFile,"\n");
    fprintf (iFile,"0x%02X,", c&0xFF);
    }
free (ROMData);
fprintf (iFile,"};\n");
fprintf (iFile, "#endif /* ROM_%s_H */\n", rom_array_name);
fclose (iFile);
if (1) { /* Set Modification Time on the include file to be the modification time of the ROM file */
    struct utimbuf times;

    times.modtime = statb.st_mtime;
    times.actime = statb.st_atime;
    utime (include_filename, &times);
    }
return 0;
}
Ejemplo n.º 16
0
int my_copy(const char *from, const char *to, myf MyFlags)
{
  size_t Count;
  my_bool new_file_stat= 0; /* 1 if we could stat "to" */
  int create_flag;
  File from_file,to_file;
  uchar buff[IO_SIZE];
  MY_STAT stat_buff,new_stat_buff;
  DBUG_ENTER("my_copy");
  DBUG_PRINT("my",("from %s to %s MyFlags %d", from, to, MyFlags));

  from_file=to_file= -1;
  DBUG_ASSERT(!(MyFlags & (MY_FNABP | MY_NABP))); /* for my_read/my_write */
  if (MyFlags & MY_HOLD_ORIGINAL_MODES)		/* Copy stat if possible */
    new_file_stat= test(my_stat((char*) to, &new_stat_buff, MYF(0)));

  if ((from_file=my_open(from,O_RDONLY | O_SHARE,MyFlags)) >= 0)
  {
    if (!my_stat(from, &stat_buff, MyFlags))
    {
      my_errno=errno;
      goto err;
    }
    if (MyFlags & MY_HOLD_ORIGINAL_MODES && new_file_stat)
      stat_buff=new_stat_buff;
    create_flag= (MyFlags & MY_DONT_OVERWRITE_FILE) ? O_EXCL : O_TRUNC;

    if ((to_file=  my_create(to,(int) stat_buff.st_mode,
			     O_WRONLY | create_flag | O_BINARY | O_SHARE,
			     MyFlags)) < 0)
      goto err;

    while ((Count=my_read(from_file, buff, sizeof(buff), MyFlags)) != 0)
    {
	if (Count == (uint) -1 ||
	    my_write(to_file,buff,Count,MYF(MyFlags | MY_NABP)))
	goto err;
    }

    /* sync the destination file */
    if (MyFlags & MY_SYNC)
    {
      if (my_sync(to_file, MyFlags))
        goto err;
    }

    if (my_close(from_file,MyFlags) | my_close(to_file,MyFlags))
      DBUG_RETURN(-1);				/* Error on close */

    /* Copy modes if possible */

    if (MyFlags & MY_HOLD_ORIGINAL_MODES && !new_file_stat)
	DBUG_RETURN(0);			/* File copyed but not stat */
    /* Copy modes */
    if (chmod(to, stat_buff.st_mode & 07777))
    {
      my_errno= errno;
      if (MyFlags & (MY_FAE+MY_WME))
      {
        char  errbuf[MYSYS_STRERROR_SIZE];
        my_error(EE_CHANGE_PERMISSIONS, MYF(ME_BELL+ME_WAITTANG), from,
                 errno, my_strerror(errbuf, sizeof(errbuf), errno));
      }
      goto err;
    }
#if !defined(__WIN__)
    /* Copy ownership */
    if (chown(to, stat_buff.st_uid, stat_buff.st_gid))
    {
      my_errno= errno;
      if (MyFlags & (MY_FAE+MY_WME))
      {
        char  errbuf[MYSYS_STRERROR_SIZE];
        my_error(EE_CHANGE_OWNERSHIP, MYF(ME_BELL+ME_WAITTANG), from,
                 errno, my_strerror(errbuf, sizeof(errbuf), errno));
      }
      goto err;
    }
#endif

    if (MyFlags & MY_COPYTIME)
    {
      struct utimbuf timep;
      timep.actime  = stat_buff.st_atime;
      timep.modtime = stat_buff.st_mtime;
      (void) utime((char*) to, &timep); /* last accessed and modified times */
    }

    DBUG_RETURN(0);
  }

err:
  if (from_file >= 0) (void) my_close(from_file,MyFlags);
  if (to_file >= 0)
  {
    (void) my_close(to_file, MyFlags);
    /* attempt to delete the to-file we've partially written */
    (void) my_delete(to, MyFlags);
  }
  DBUG_RETURN(-1);
} /* my_copy */
int main(int ac, char **av)
{
	struct stat stat_buf;	/* struct buffer to hold file info. */
	int lc;
	long type;
	time_t modf_time, access_time;
	time_t pres_time;	/* file modification/access/present time */

	tst_parse_opts(ac, av, NULL, NULL);

	setup();

	switch ((type = tst_fs_type(cleanup, "."))) {
	case TST_NFS_MAGIC:
		if (tst_kvercmp(2, 6, 18) < 0)
			tst_brkm(TCONF, cleanup, "Cannot do utime on a file"
				" on %s filesystem before 2.6.18",
				 tst_fs_type_name(type));
		break;
	case TST_V9FS_MAGIC:
		tst_brkm(TCONF, cleanup,
			 "Cannot do utime on a file on %s filesystem",
			 tst_fs_type_name(type));
		break;
	}

	for (lc = 0; TEST_LOOPING(lc); lc++) {

		tst_count = 0;

		/*
		 * Invoke utime(2) to set TEMP_FILE access and
		 * modification times to the current time.
		 */
		TEST(utime(TEMP_FILE, NULL));

		if (TEST_RETURN == -1) {
			tst_resm(TFAIL, "utime(%s) Failed, errno=%d : %s",
				 TEMP_FILE, TEST_ERRNO, strerror(TEST_ERRNO));
		} else {
			/*
			 * Sleep for a second so that mod time and
			 * access times will be different from the
			 * current time
			 */
			sleep(2);

			/*
			 * Get the current time now, after calling
			 * utime(2)
			 */
			if ((pres_time = time(&tloc)) < 0) {
				tst_brkm(TFAIL, cleanup, "time() "
					 "failed to get present time "
					 "after utime, error=%d",
					 errno);
			}

			/*
			 * Get the modification and access times of
			 * temporary file using stat(2).
			 */
			if (stat(TEMP_FILE, &stat_buf) < 0) {
				tst_brkm(TFAIL, cleanup, "stat(2) of "
					 "%s failed, error:%d",
					 TEMP_FILE, TEST_ERRNO);
			}
			modf_time = stat_buf.st_mtime;
			access_time = stat_buf.st_atime;

			/* Now do the actual verification */
			if (modf_time <= curr_time ||
			    modf_time >= pres_time ||
			    access_time <= curr_time ||
			    access_time >= pres_time) {
				tst_resm(TFAIL, "%s access and "
					 "modification times not set",
					 TEMP_FILE);
			} else {
				tst_resm(TPASS, "Functionality of "
					 "utime(%s, NULL) successful",
					 TEMP_FILE);
			}
		}
		tst_count++;
	}

	cleanup();
	tst_exit();
}
Ejemplo n.º 18
0
int
main(int argc, char **argv)
{
    int onlydir, dodir, dolink, dorelsymlink, dotimes, opt, len, lplen, tdlen, bnlen, exists, fromfd, tofd, cc, wc;
    mode_t mode = 0755;
    char *linkprefix, *owner, *group, *cp, *cwd, *todir, *toname, *name, *base, *linkname, *bp, buf[BUFSIZ];
    uid_t uid;
    gid_t gid;
    struct stat sb, tosb;
    struct utimbuf utb;

    program = argv[0];
    cwd = linkname = linkprefix = owner = group = 0;
    onlydir = dodir = dolink = dorelsymlink = dotimes = lplen = 0;

    while ((opt = getopt(argc, argv, "C:DdlL:Rm:o:g:t")) != EOF) {
	switch (opt) {
	  case 'C':
	    cwd = optarg;
	    break;
	  case 'D':
	    onlydir = 1;
	    break;
	  case 'd':
	    dodir = 1;
	    break;
	  case 'l':
	    dolink = 1;
	    break;
	  case 'L':
	    linkprefix = optarg;
	    lplen = strlen(linkprefix);
	    dolink = 1;
	    break;
	  case 'R':
	    dolink = dorelsymlink = 1;
	    break;
	  case 'm':
	    mode = strtoul(optarg, &cp, 8);
	    if (mode == 0 && cp == optarg)
		usage();
	    break;
	  case 'o':
	    owner = optarg;
	    break;
	  case 'g':
	    group = optarg;
	    break;
	  case 't':
	    dotimes = 1;
	    break;
	  default:
	    usage();
	}
    }

    argc -= optind;
    argv += optind;
    if (argc < 2 - onlydir)
	usage();

    todir = argv[argc-1];
    if ((stat(todir, &sb) < 0 || !S_ISDIR(sb.st_mode)) &&
	mkdirs(todir, 0777) < 0) {
	fail("cannot make directory %s", todir);
    }
    if (onlydir)
	return 0;

    if (!cwd) {
#ifdef GETCWD_CAN_MALLOC
	cwd = getcwd(0, PATH_MAX);
#else
	cwd = malloc(PATH_MAX + 1);
	cwd = getcwd(cwd, PATH_MAX);
#endif
    }
    xchdir(todir);
#ifdef GETCWD_CAN_MALLOC
    todir = getcwd(0, PATH_MAX);
#else
    todir = malloc(PATH_MAX + 1);
    todir = getcwd(todir, PATH_MAX);
#endif
    tdlen = strlen(todir);
    xchdir(cwd);
    tdlen = strlen(todir);

    uid = owner ? touid(owner) : -1;
    gid = group ? togid(group) : -1;

    while (--argc > 0) {
	name = *argv++;
	len = strlen(name);
	base = xbasename(name);
	bnlen = strlen(base);
	toname = (char*)xmalloc(tdlen + 1 + bnlen + 1);
	sprintf(toname, "%s/%s", todir, base);
	exists = (lstat(toname, &tosb) == 0);

	if (dodir) {
	    /* -d means create a directory, always */
	    if (exists && !S_ISDIR(tosb.st_mode)) {
		(void) unlink(toname);
		exists = 0;
	    }
	    if (!exists && mkdir(toname, mode) < 0)
		fail("cannot make directory %s", toname);
	    if ((owner || group) && chown(toname, uid, gid) < 0)
		fail("cannot change owner of %s", toname);
	} else if (dolink) {
	    if (*name == '/') {
		/* source is absolute pathname, link to it directly */
		linkname = 0;
	    } else {
		if (linkprefix) {
		    /* -L implies -l and prefixes names with a $cwd arg. */
		    len += lplen + 1;
		    linkname = (char*)xmalloc(len + 1);
		    sprintf(linkname, "%s/%s", linkprefix, name);
		} else if (dorelsymlink) {
		    /* Symlink the relative path from todir to source name. */
		    linkname = (char*)xmalloc(PATH_MAX);

		    if (*todir == '/') {
			/* todir is absolute: skip over common prefix. */
			lplen = relatepaths(todir, cwd, linkname);
			strcpy(linkname + lplen, name);
		    } else {
			/* todir is named by a relative path: reverse it. */
			reversepath(todir, name, len, linkname);
			xchdir(cwd);
		    }

		    len = strlen(linkname);
		}
		name = linkname;
	    }

	    /* Check for a pre-existing symlink with identical content. */
	    if (exists &&
		(!S_ISLNK(tosb.st_mode) ||
		 readlink(toname, buf, sizeof buf) != len ||
		 strncmp(buf, name, len) != 0)) {
		(void) (S_ISDIR(tosb.st_mode) ? rmdir : unlink)(toname);
		exists = 0;
	    }
	    if (!exists && symlink(name, toname) < 0)
		fail("cannot make symbolic link %s", toname);
#ifdef HAVE_LCHOWN
	    if ((owner || group) && lchown(toname, uid, gid) < 0)
		fail("cannot change owner of %s", toname);
#endif

	    if (linkname) {
		free(linkname);
		linkname = 0;
	    }
	} else {
	    /* Copy from name to toname, which might be the same file. */
	    fromfd = open(name, O_RDONLY);
	    if (fromfd < 0 || fstat(fromfd, &sb) < 0)
		fail("cannot access %s", name);
	    if (exists && (!S_ISREG(tosb.st_mode) || access(toname, W_OK) < 0))
		(void) (S_ISDIR(tosb.st_mode) ? rmdir : unlink)(toname);
	    tofd = open(toname, O_CREAT | O_WRONLY, 0666);
	    if (tofd < 0)
		fail("cannot create %s", toname);

	    bp = buf;
	    while ((cc = read(fromfd, bp, sizeof buf)) > 0) {
		while ((wc = write(tofd, bp, cc)) > 0) {
		    if ((cc -= wc) == 0)
			break;
		    bp += wc;
		}
		if (wc < 0)
		    fail("cannot write to %s", toname);
	    }
	    if (cc < 0)
		fail("cannot read from %s", name);

	    if (ftruncate(tofd, sb.st_size) < 0)
		fail("cannot truncate %s", toname);
	    if (dotimes) {
		utb.actime = sb.st_atime;
		utb.modtime = sb.st_mtime;
		if (utime(toname, &utb) < 0)
		    fail("cannot set times of %s", toname);
	    }
#ifdef HAVE_FCHMOD
	    if (fchmod(tofd, mode) < 0)
#else
	    if (chmod(toname, mode) < 0)
#endif
		fail("cannot change mode of %s", toname);
	    if ((owner || group) && fchown(tofd, uid, gid) < 0)
		fail("cannot change owner of %s", toname);

	    /* Must check for delayed (NFS) write errors on close. */
	    if (close(tofd) < 0)
		fail("cannot write to %s", toname);
	    close(fromfd);
	}

	free(toname);
    }

    free(cwd);
    free(todir);
    return 0;
}
Ejemplo n.º 19
0
static ssize_t uv__fs_utime(uv_fs_t* req) {
  struct utimbuf buf;
  buf.actime = req->atime;
  buf.modtime = req->mtime;
  return utime(req->path, &buf); /* TODO use utimes() where available */
}
Ejemplo n.º 20
0
int dexopt(const char *apk_path, uid_t uid, int is_public)
{
    struct utimbuf ut;
    struct stat apk_stat, dex_stat;
    char out_path[PKG_PATH_MAX];
    char dexopt_flags[PROPERTY_VALUE_MAX];
    char persist_sys_dalvik_vm_lib[PROPERTY_VALUE_MAX];
    char *end;
    int res, zip_fd=-1, out_fd=-1;

    if (strlen(apk_path) >= (PKG_PATH_MAX - 8)) {
        return -1;
    }

    /* platform-specific flags affecting optimization and verification */
    property_get("dalvik.vm.dexopt-flags", dexopt_flags, "");
    ALOGV("dalvik.vm.dexopt_flags=%s\n", dexopt_flags);

    /* The command to run depend ones the value of persist.sys.dalvik.vm.lib */
    property_get("persist.sys.dalvik.vm.lib", persist_sys_dalvik_vm_lib, "libdvm.so");

    /* Before anything else: is there a .odex file?  If so, we have
     * precompiled the apk and there is nothing to do here.
     */
    sprintf(out_path, "%s%s", apk_path, ".odex");
    if (stat(out_path, &dex_stat) == 0) {
        return 0;
    }

    if (create_cache_path(out_path, apk_path)) {
        return -1;
    }

    memset(&apk_stat, 0, sizeof(apk_stat));
    stat(apk_path, &apk_stat);

    zip_fd = open(apk_path, O_RDONLY, 0);
    if (zip_fd < 0) {
        ALOGE("installd cannot open '%s' for input during dexopt\n", apk_path);
        return -1;
    }

    unlink(out_path);
    out_fd = open(out_path, O_RDWR | O_CREAT | O_EXCL, 0644);
    if (out_fd < 0) {
        ALOGE("installd cannot open '%s' for output during dexopt\n", out_path);
        goto fail;
    }
    if (fchmod(out_fd,
               S_IRUSR|S_IWUSR|S_IRGRP |
               (is_public ? S_IROTH : 0)) < 0) {
        ALOGE("installd cannot chmod '%s' during dexopt\n", out_path);
        goto fail;
    }
    if (fchown(out_fd, AID_SYSTEM, uid) < 0) {
        ALOGE("installd cannot chown '%s' during dexopt\n", out_path);
        goto fail;
    }

    ALOGV("DexInv: --- BEGIN '%s' ---\n", apk_path);

    pid_t pid;
    pid = fork();
    if (pid == 0) {
        /* child -- drop privileges before continuing */
        if (setgid(uid) != 0) {
            ALOGE("setgid(%d) failed in installd during dexopt\n", uid);
            exit(64);
        }
        if (setuid(uid) != 0) {
            ALOGE("setuid(%d) failed in installd during dexopt\n", uid);
            exit(65);
        }
        // drop capabilities
        struct __user_cap_header_struct capheader;
        struct __user_cap_data_struct capdata[2];
        memset(&capheader, 0, sizeof(capheader));
        memset(&capdata, 0, sizeof(capdata));
        capheader.version = _LINUX_CAPABILITY_VERSION_3;
        if (capset(&capheader, &capdata[0]) < 0) {
            ALOGE("capset failed: %s\n", strerror(errno));
            exit(66);
        }
        if (flock(out_fd, LOCK_EX | LOCK_NB) != 0) {
            ALOGE("flock(%s) failed: %s\n", out_path, strerror(errno));
            exit(67);
        }

        if (strncmp(persist_sys_dalvik_vm_lib, "libdvm", 6) == 0) {
            run_dexopt(zip_fd, out_fd, apk_path, out_path, dexopt_flags);
        } else if (strncmp(persist_sys_dalvik_vm_lib, "libart", 6) == 0) {
            run_dex2oat(zip_fd, out_fd, apk_path, out_path, dexopt_flags);
        } else {
            exit(69);   /* Unexpected persist.sys.dalvik.vm.lib value */
        }
        exit(68);   /* only get here on exec failure */
    } else {
        res = wait_dexopt(pid, apk_path);
        if (res != 0) {
            ALOGE("dexopt in='%s' out='%s' res=%d\n", apk_path, out_path, res);
            goto fail;
        }
    }

    ut.actime = apk_stat.st_atime;
    ut.modtime = apk_stat.st_mtime;
    utime(out_path, &ut);

    close(out_fd);
    close(zip_fd);
    return 0;

fail:
    if (out_fd >= 0) {
        close(out_fd);
        unlink(out_path);
    }
    if (zip_fd >= 0) {
        close(zip_fd);
    }
    return -1;
}
Ejemplo n.º 21
0
int main(int ac, char **av)
{
	struct stat stat_buf;	/* struct buffer to hold file info. */
	int lc;
	long type;
	const char *msg;
	time_t modf_time, access_time;
	time_t pres_time;	/* file modification/access/present time */
	pid_t pid;

	msg = parse_opts(ac, av, NULL, NULL);
	if (msg != NULL) {
		tst_brkm(TBROK, NULL, "OPTION PARSING ERROR - %s", msg);

	}

	setup();

	switch ((type = tst_fs_type(cleanup, "."))) {
	case TST_NFS_MAGIC:
	case TST_V9FS_MAGIC:
		tst_brkm(TCONF, cleanup,
			 "Cannot do utime on a file on %s filesystem",
			 tst_fs_type_name(type));
	break;
	}

	/* set the expected errnos... */
	TEST_EXP_ENOS(exp_enos);

	pid = FORK_OR_VFORK();

	if (pid == -1) {
		tst_brkm(TBROK, cleanup, "fork() failed");
	} else if (pid == 0) {
		if ((ltpuser = getpwnam(LTPUSER1)) == NULL) {
			tst_brkm(TBROK, cleanup, "%s not found in /etc/passwd",
				 LTPUSER1);
		}

		/* get uid/gid of user accordingly */
		user_uid = ltpuser->pw_uid;

		seteuid(user_uid);

		for (lc = 0; TEST_LOOPING(lc); lc++) {

			tst_count = 0;

			/*
			 * Invoke utime(2) to set TEMP_FILE access and
			 * modification times to the current time.
			 */
			TEST(utime(TEMP_FILE, NULL));

			if (TEST_RETURN == -1) {
				TEST_ERROR_LOG(TEST_ERRNO);
				tst_resm(TFAIL,
					 "utime(%s) Failed, errno=%d : %s",
					 TEMP_FILE, TEST_ERRNO,
					 strerror(TEST_ERRNO));
			} else {
				/*
				 * Sleep for a second so that mod time
				 * and access times will be different
				 * from the current time.
				 */
				sleep(2);

				/*
				 * Get the current time now, after
				 * calling utime(2)
				 */
				if ((pres_time = time(&tloc)) < 0) {
					tst_brkm(TFAIL, cleanup,
						 "time() failed to get "
						 "present time after "
						 "utime, error=%d",
						 errno);
				}

				/*
				 * Get the modification and access
				 * times of temporary file using
				 * stat(2).
				 */
				if (stat(TEMP_FILE, &stat_buf) < 0) {
					tst_brkm(TFAIL, cleanup,
						 "stat(2) of %s failed, "
						 "error:%d", TEMP_FILE,
						 TEST_ERRNO);
				}
				modf_time = stat_buf.st_mtime;
				access_time = stat_buf.st_atime;

				/* Now do the actual verification */
				if (modf_time <= curr_time ||
				    modf_time >= pres_time ||
				    access_time <= curr_time ||
				    access_time >= pres_time) {
					tst_resm(TFAIL, "%s access and "
						 "modification times "
						 "not set", TEMP_FILE);
				} else {
					tst_resm(TPASS, "Functionality "
						 "of utime(%s, NULL) "
						 "successful",
						 TEMP_FILE);
				}
			}
			tst_count++;	/* incr. TEST_LOOP counter */
		}
	} else {
		waitpid(pid, &status, 0);
		_exit(0);	/*
				 * Exit here and let the child clean up.
				 * This allows the errno information set
				 * by the TEST_ERROR_LOG macro and the
				 * PASS/FAIL status to be preserved for
				 * use during cleanup.
				 */
	}

	cleanup();
	tst_exit();

}
Ejemplo n.º 22
0
int main(int argc, char **argv)
{
int  lock_retries = 10;
int  lock_interval = 3;
int  lock_fcntl_timeout = 0;
int  lock_flock_timeout = 0;
int  i, j, len;
int  fd = -1;
int  hd = -1;
int  md = -1;
int  yield = 0;
int  now = time(NULL);
BOOL use_lockfile = FALSE;
BOOL use_fcntl = FALSE;
BOOL use_flock = FALSE;
BOOL use_mbx = FALSE;
BOOL verbose = FALSE;
BOOL quiet = FALSE;
BOOL restore_times = FALSE;
char *filename;
char *lockname = NULL, *hitchname = NULL;
char *primary_hostname;
const char *command;
struct utsname s;
char buffer[256];
char tempname[256];

/* Decode options */

for (i = 1; i < argc; i++)
  {
  char *arg = argv[i];
  if (*arg != '-') break;
  if (strcmp(arg, "-fcntl") == 0) use_fcntl = TRUE;
  else if (strcmp(arg, "-flock") == 0) use_flock = TRUE;
  else if (strcmp(arg, "-lockfile") == 0) use_lockfile = TRUE;
  else if (strcmp(arg, "-mbx") == 0) use_mbx = TRUE;
  else if (strcmp(arg, "-v") == 0) verbose = TRUE;
  else if (strcmp(arg, "-q") == 0) quiet = TRUE;
  else if (strcmp(arg, "-restore-times") == 0) restore_times = TRUE;
  else if (++i < argc)
    {
    int value = atoi(argv[i]);
    if (strcmp(arg, "-retries") == 0) lock_retries = value;
    else if (strcmp(arg, "-interval") == 0) lock_interval = value;
    else if (strcmp(arg, "-timeout") == 0)
      lock_fcntl_timeout = lock_flock_timeout = value;
    else usage();
    }
  else usage();
  }

if (quiet) verbose = 0;

/* Can't use flock() if the OS doesn't provide it */

#ifdef NO_FLOCK
if (use_flock)
  {
  printf("exim_lock: can't use flock() because it was not available in the\n"
         "           operating system when exim_lock was compiled\n");
  exit(1);
  }
#endif

/* Default is to use lockfiles and fcntl(). */

if (!use_lockfile && !use_fcntl && !use_flock && !use_mbx)
  use_lockfile = use_fcntl = TRUE;

/* Default fcntl() for use with mbx */

if (use_mbx && !use_fcntl && !use_flock) use_fcntl = TRUE;

/* Unset unused timeouts */

if (!use_fcntl) lock_fcntl_timeout = 0;
if (!use_flock) lock_flock_timeout = 0;

/* A file name is required */

if (i >= argc) usage();

filename = argv[i++];

/* Expand file names starting with ~ */

if (*filename == '~')
  {
  struct passwd *pw;

  if (*(++filename) == '/')
    pw = getpwuid(getuid());
  else
    {
    char *s = buffer;
    while (*filename != 0 && *filename != '/')
      *s++ = *filename++;
    *s = 0;
    pw = getpwnam(buffer);
    }

  if (pw == NULL)
    {
    printf("exim_lock: unable to expand file name %s\n", argv[i-1]);
    exit(1);
    }

  if ((int)strlen(pw->pw_dir) + (int)strlen(filename) + 1 > sizeof(buffer))
    {
    printf("exim_lock: expanded file name %s%s is too long", pw->pw_dir,
      filename);
    exit(1);
    }

  strcpy(buffer, pw->pw_dir);
  strcat(buffer, filename);
  filename = buffer;
  }

/* If using a lock file, prepare by creating the lock file name and
the hitching post name. */

if (use_lockfile)
  {
  if (uname(&s) < 0)
    {
    printf("exim_lock: failed to find host name using uname()\n");
    exit(1);
    }
  primary_hostname = s.nodename;

  len = (int)strlen(filename);
  lockname = malloc(len + 8);
  sprintf(lockname, "%s.lock", filename);
  hitchname = malloc(len + 32 + (int)strlen(primary_hostname));
  sprintf(hitchname, "%s.%s.%08x.%08x", lockname, primary_hostname,
    now, (int)getpid());

  if (verbose)
    printf("exim_lock: lockname =  %s\n           hitchname = %s\n", lockname,
      hitchname);
  }

/* Locking retry loop */

for (j = 0; j < lock_retries; j++)
  {
  int sleep_before_retry = TRUE;
  struct stat statbuf, ostatbuf, lstatbuf, statbuf2;
  int mbx_tmp_oflags;

  /* Try to build a lock file if so configured */

  if (use_lockfile)
    {
    int rc;
    if (verbose) printf("exim_lock: creating lock file\n");
    hd = open(hitchname, O_WRONLY | O_CREAT | O_EXCL, 0440);
    if (hd < 0)
      {
      printf("exim_lock: failed to create hitching post %s: %s\n", hitchname,
        strerror(errno));
      exit(1);
      }

    /* Apply hitching post algorithm. */

    if ((rc = link(hitchname, lockname)) != 0) fstat(hd, &statbuf);
    (void)close(hd);
    unlink(hitchname);

    if (rc != 0 && statbuf.st_nlink != 2)
      {
      printf("exim_lock: failed to link hitching post to lock file\n");
      hd = -1;
      goto RETRY;
      }

    if (!quiet) printf("exim_lock: lock file successfully created\n");
    }

  /* We are done if no other locking required. */

  if (!use_fcntl && !use_flock && !use_mbx) break;

  /* Open the file for writing. */

  fd = open(filename, O_RDWR + O_APPEND);
  if (fd < 0)
    {
    printf("exim_lock: failed to open %s for writing: %s\n", filename,
      strerror(errno));
    yield = 1;
    goto CLEAN_UP;
    }

  /* If there is a timeout, implying blocked locking, we don't want to
  sleep before any retries after this. */

  if (lock_fcntl_timeout > 0 || lock_flock_timeout > 0)
    sleep_before_retry = FALSE;

  /* Lock using fcntl. There are pros and cons to using a blocking call vs
  a non-blocking call and retries. Exim is non-blocking by default, but setting
  a timeout changes it to blocking. */

  if (!use_mbx && (use_fcntl || use_flock))
    {
    if (apply_lock(fd, F_WRLCK, use_fcntl, lock_fcntl_timeout, use_flock,
        lock_flock_timeout) >= 0)
      {
      if (!quiet)
        {
        if (use_fcntl) printf("exim_lock: fcntl() lock successfully applied\n");
        if (use_flock) printf("exim_lock: flock() lock successfully applied\n");
        }
      break;
      }
    else goto RETRY;   /* Message already output */
    }

  /* Lock using MBX rules. This is complicated and is documented with the
  source of the c-client library that goes with Pine and IMAP. What has to
  be done to interwork correctly is to take out a shared lock on the mailbox,
  and an exclusive lock on a /tmp file. */

  else
    {
    if (apply_lock(fd, F_RDLCK, use_fcntl, lock_fcntl_timeout, use_flock,
        lock_flock_timeout) >= 0)
      {
      if (!quiet)
        {
        if (use_fcntl)
          printf("exim_lock: fcntl() read lock successfully applied\n");
        if (use_flock)
          printf("exim_lock: fcntl() read lock successfully applied\n");
        }
      }
    else goto RETRY;   /* Message already output */

    if (fstat(fd, &statbuf) < 0)
      {
      printf("exim_lock: fstat() of %s failed: %s\n", filename,
        strerror(errno));
      yield = 1;
      goto CLEAN_UP;
      }

    /* Set up file in /tmp and check its state if already existing. */

    sprintf(tempname, "/tmp/.%lx.%lx", (long)statbuf.st_dev,
      (long)statbuf.st_ino);

    if (lstat(tempname, &statbuf) >= 0)
      {
      if ((statbuf.st_mode & S_IFMT) == S_IFLNK)
        {
        printf("exim_lock: symbolic link on lock name %s\n", tempname);
        yield = 1;
        goto CLEAN_UP;
        }
      if (statbuf.st_nlink > 1)
        {
        printf("exim_lock: hard link to lock name %s\n", tempname);
        yield = 1;
        goto CLEAN_UP;
        }
      }

    mbx_tmp_oflags = O_RDWR | O_CREAT;
#ifdef O_NOFOLLOW
    mbx_tmp_oflags |= O_NOFOLLOW;
#endif
    md = open(tempname, mbx_tmp_oflags, 0600);
    if (md < 0)
      {
      printf("exim_lock: failed to create mbx lock file %s: %s\n",
        tempname, strerror(errno));
      goto CLEAN_UP;
      }

    /* security fixes from 2010-05 */
    if (lstat(tempname, &lstatbuf) < 0)
      {
      printf("exim_lock: failed to lstat(%s) after opening it: %s\n",
          tempname, strerror(errno));
      goto CLEAN_UP;
      }
    if (fstat(md, &statbuf2) < 0)
      {
      printf("exim_lock: failed to fstat() open fd of \"%s\": %s\n",
          tempname, strerror(errno));
      goto CLEAN_UP;
      }
    if ((statbuf2.st_nlink > 1) ||
        (lstatbuf.st_nlink > 1) ||
        (!S_ISREG(lstatbuf.st_mode)) ||
        (lstatbuf.st_dev != statbuf2.st_dev) ||
        (lstatbuf.st_ino != statbuf2.st_ino))
      {
      printf("exim_lock: race condition exploited against us when "
          "locking \"%s\"\n", tempname);
      goto CLEAN_UP;
      }

    (void)chmod(tempname, 0600);

    if (apply_lock(md, F_WRLCK, use_fcntl, lock_fcntl_timeout, use_flock,
        lock_flock_timeout) >= 0)
      {
      if (!quiet)
        {
        if (use_fcntl)
          printf("exim_lock: fcntl() lock successfully applied to mbx "
            "lock file %s\n", tempname);
        if (use_flock)
          printf("exim_lock: flock() lock successfully applied to mbx "
            "lock file %s\n", tempname);
        }

      /* This test checks for a race condition */

      if (lstat(tempname, &statbuf) != 0 ||
          fstat(md, &ostatbuf) != 0 ||
          statbuf.st_dev != ostatbuf.st_dev ||
          statbuf.st_ino != ostatbuf.st_ino)
       {
       if (!quiet) printf("exim_lock: mbx lock file %s changed between "
           "creation and locking\n", tempname);
       goto RETRY;
       }
      else break;
      }
    else goto RETRY;   /* Message already output */
    }

  /* Clean up before retrying */

  RETRY:

  if (md >= 0)
    {
    if (close(md) < 0)
      printf("exim_lock: close %s failed: %s\n", tempname, strerror(errno));
    else
      if (!quiet) printf("exim_lock: %s closed\n", tempname);
    md = -1;
    }

  if (fd >= 0)
    {
    if (close(fd) < 0)
      printf("exim_lock: close failed: %s\n", strerror(errno));
    else
      if (!quiet) printf("exim_lock: file closed\n");
    fd = -1;
    }

  if (hd >= 0)
    {
    if (unlink(lockname) < 0)
      printf("exim_lock: unlink of %s failed: %s\n", lockname, strerror(errno));
    else
      if (!quiet) printf("exim_lock: lock file removed\n");
    hd = -1;
    }

  /* If a blocking call timed out, break the retry loop if the total time
  so far is not less than than retries * interval. */

  if (sigalrm_seen &&
      (j + 1) * ((lock_fcntl_timeout > lock_flock_timeout)?
        lock_fcntl_timeout : lock_flock_timeout) >=
          lock_retries * lock_interval)
    j = lock_retries;

  /* Wait a bit before retrying, except when it was a blocked fcntl() that
  caused the problem. */

  if (j < lock_retries && sleep_before_retry)
    {
    printf(" ... waiting\n");
    sleep(lock_interval);
    }
  }

if (j >= lock_retries)
  {
  printf("exim_lock: locking failed too many times\n");
  yield = 1;
  goto CLEAN_UP;
  }

if (!quiet) printf("exim_lock: locking %s succeeded: ", filename);

/* If there are no further arguments, run the user's shell; otherwise
the next argument is a command to run. */

if (i >= argc)
  {
  command = getenv("SHELL");
  if (command == NULL || *command == 0) command = "/bin/sh";
  if (!quiet) printf("running %s ...\n", command);
  }
else
  {
  command = argv[i];
  if (!quiet) printf("running the command ...\n");
  }

/* Run the command, saving and restoring the times if required. */

if (restore_times)
  {
  struct stat strestore;
  struct utimbuf ut;
  stat(filename, &strestore);
  (void)system(command);
  ut.actime = strestore.st_atime;
  ut.modtime = strestore.st_mtime;
  utime(filename, &ut);
  }
else (void)system(command);

/* Remove the locks and exit. Unlink the /tmp file if we can get an exclusive
lock on the mailbox. This should be a non-blocking lock call, as there is no
point in waiting. */

CLEAN_UP:

if (md >= 0)
  {
  if (apply_lock(fd, F_WRLCK, use_fcntl, 0, use_flock, 0) >= 0)
    {
    if (!quiet) printf("exim_lock: %s unlinked - no sharers\n", tempname);
    unlink(tempname);
    }
  else if (!quiet)
    printf("exim_lock: %s not unlinked - unable to get exclusive mailbox lock\n",
      tempname);
  if (close(md) < 0)
    printf("exim_lock: close %s failed: %s\n", tempname, strerror(errno));
  else
    if (!quiet) printf("exim_lock: %s closed\n", tempname);
  }

if (fd >= 0)
  {
  if (close(fd) < 0)
    printf("exim_lock: close %s failed: %s\n", filename, strerror(errno));
  else
    if (!quiet) printf("exim_lock: %s closed\n", filename);
  }

if (hd >= 0)
  {
  if (unlink(lockname) < 0)
    printf("exim_lock: unlink %s failed: %s\n", lockname, strerror(errno));
  else
    if (!quiet) printf("exim_lock: lock file removed\n");
  }

return yield;
}
Ejemplo n.º 23
0
int move_file(struct flist * file, off_t wsize)
{
	char *from, *to, *buf;
	off_t size;
	FILE *input, *output;
	int ret, dir_id;
	struct utimbuf ftime = {0};
	struct statvfs svf;
	fsblkcnt_t space;
	struct stat st;

	mhdd_debug(MHDD_MSG, "move_file: %s\n", file->real_name);

	/* TODO: it would be nice to contrive something alter */
	flist_wrlock_locked();
	from=file->real_name;

	/* We need to check if already moved */
	if (statvfs(from, &svf) != 0)
		return -errno;
	space = svf.f_bsize;
	space *= svf.f_bavail;

	/* get file size */
	if (fstat(file->fh, &st) != 0) {
		mhdd_debug(MHDD_MSG, "move_file: error stat %s: %s\n",
			from, strerror(errno));
		return -errno;
	}

        /* Hard link support is limited to a single device, and files with
           >1 hardlinks cannot be moved between devices since this would
           (a) result in partial files on the source device (b) not free
           the space from the source device during unlink. */
	if (st.st_nlink > 1) {
		mhdd_debug(MHDD_MSG, "move_file: cannot move "
			"files with >1 hardlinks\n");
		return -ENOTSUP;
	}

	size = st.st_size;
	if (size < wsize) size=wsize;

	if (space > size) {
		mhdd_debug(MHDD_MSG, "move_file: we have enough space\n");
		return 0;
	}

	if ((dir_id=find_free_space(size)) == -1) {
		mhdd_debug(MHDD_MSG, "move_file: can not find space\n");
		return -1;
	}

	if (!(input = fopen(from, "r")))
		return -errno;

	create_parent_dirs(dir_id, file->name);

	to = create_path(mhdd.dirs[dir_id], file->name);
	if (!(output = fopen(to, "w+"))) {
		ret = -errno;
		mhdd_debug(MHDD_MSG, "move_file: error create %s: %s\n",
				to, strerror(errno));
		free(to);
		fclose(input);
		return(ret);
	}

	mhdd_debug(MHDD_MSG, "move_file: move %s to %s\n", from, to);

	// move data
	buf=(char *)calloc(sizeof(char), MOVE_BLOCK_SIZE);
	while((size = fread(buf, sizeof(char), MOVE_BLOCK_SIZE, input))) {
		if (size != fwrite(buf, sizeof(char), size, output)) {
			mhdd_debug(MHDD_MSG,
				"move_file: error move data to %s: %s\n",
				to, strerror(errno));
			fclose(output);
			fclose(input);
			free(buf);
			unlink(to);
			free(to);
			return -1;
		}
	}
	free(buf);

	mhdd_debug(MHDD_MSG, "move_file: done move data\n");
	fclose(input);

	// owner/group/permissions
	fchmod(fileno(output), st.st_mode);
	fchown(fileno(output), st.st_uid, st.st_gid);
	fclose(output);

	// time
	ftime.actime = st.st_atime;
	ftime.modtime = st.st_mtime;
	utime(to, &ftime);

#ifndef WITHOUT_XATTR
        // extended attributes
        if (copy_xattrs(from, to) == -1)
            mhdd_debug(MHDD_MSG,
                    "copy_xattrs: error copying xattrs from %s to %s\n",
                    from, to);
#endif


	from = strdup(from);
	if ((ret = reopen_files(file, to)) == 0)
		unlink(from);
	else
		unlink(to);

	mhdd_debug(MHDD_MSG, "move_file: %s -> %s: done, code=%d\n",
		from, to, ret);
	free(to);
	free(from);
	return ret;
}
Ejemplo n.º 24
0
int sim_make_ROM_include(const char *rom_filename,
                         int expected_size,
                         int expected_checksum,
                         const char *include_filename, 
                         const char *rom_array_name)
{
FILE *rFile;
FILE *iFile;
time_t now;
int bytes_written = 0;
int c;
struct stat statb;
unsigned char *ROMData = NULL;
unsigned int checksum = 0;

if (NULL == (rFile = fopen (rom_filename, "rb"))) {
    printf ("Error Opening '%s' for input: %s\n", rom_filename, strerror(errno));
    return -1;
    }
if (stat (rom_filename, &statb)) {
    printf ("Error stating '%s': %s\n", rom_filename, strerror(errno));
    fclose (rFile);
    return -1;
    }
if (statb.st_size != expected_size) {
    printf ("Error: ROM file '%s' has an unexpected size: %d vs %d\n", rom_filename, (int)statb.st_size, expected_size);
    printf ("This can happen if the file was transferred or unpacked incorrectly\n");
    printf ("and in the process tried to convert line endings rather than passing\n");
    printf ("the file's contents unmodified\n");
    fclose (rFile);
    return -1;
    }
ROMData = malloc (statb.st_size);
if (statb.st_size != fread (ROMData, sizeof(*ROMData), statb.st_size, rFile)) {
    printf ("Error reading '%s': %s\n", rom_filename, strerror(errno));
    fclose (rFile);
    free (ROMData);
    return -1;
    }
fclose (rFile);
for (c=0; c<statb.st_size; ++c)
    checksum += ROMData[c];
checksum = ~checksum;
if ((expected_checksum != 0) && (checksum != expected_checksum)) {
    printf ("Error: ROM file '%s' has an unexpected checksum: 0x%08X vs 0x%08X\n", rom_filename, checksum, expected_checksum);
    printf ("This can happen if the file was transferred or unpacked incorrectly\n");
    printf ("and in the process tried to convert line endings rather than passing\n");
    printf ("the file's contents unmodified\n");
    fclose (rFile);
    return -1;
    }
/*
 * If the target include file already exists, determine if it contains the exact
 * data in the base ROM image.  If so, then we are already done
 */
if (iFile = fopen (include_filename, "r")) {
    unsigned char *IncludeData = NULL;
    char line[256];
    int Difference = 0;

    IncludeData = malloc (statb.st_size);

    while (fgets (line, sizeof(line), iFile)) {
        int byte;
        char *c;

        if (memcmp ("0x",line,2))
            continue;
        c = line;
        while (1 == sscanf (c, "0x%2Xd,", &byte)) {
            if (bytes_written >= statb.st_size)
                Difference = 1;
            else
                IncludeData[bytes_written++] = byte;
            c += 5;
            }
        if ((strchr (line,'}')) || Difference)
            break;
        }
    fclose (iFile);
    if (!Difference)
        Difference = memcmp (IncludeData, ROMData, statb.st_size);
    free (IncludeData);
    if (!Difference) {
        free (ROMData);
        return 0;
        }
    }

if (NULL == (iFile = fopen (include_filename, "w"))) {
    printf ("Error Opening '%s' for output: %s\n", include_filename, strerror(errno));
    return -1;
    }
time (&now);
fprintf (iFile, "#ifndef ROM_%s_H\n", rom_array_name);
fprintf (iFile, "#define ROM_%s_H 0\n", rom_array_name);
fprintf (iFile, "/*\n");
fprintf (iFile, "   %s         produced at %s", include_filename, ctime(&now));
fprintf (iFile, "   from %s which was last modified at %s", rom_filename, ctime(&statb.st_mtime));
fprintf (iFile, "   file size: %d (0x%X) - checksum: 0x%08X\n", (int)statb.st_size, (int)statb.st_size, checksum);
fprintf (iFile, "*/\n");
fprintf (iFile, "unsigned char %s[] = {", rom_array_name);
for (bytes_written=0;bytes_written<statb.st_size; ++bytes_written) {
    c = ROMData[bytes_written];
    if (0 == bytes_written%16)
        fprintf (iFile,"\n");
    fprintf (iFile,"0x%02X,", c&0xFF);
    }
free (ROMData);
fprintf (iFile,"};\n");
fprintf (iFile, "#endif /* ROM_%s_H */\n", rom_array_name);
fclose (iFile);
if (1) { /* Set Modification Time on the include file to be the modification time of the ROM file */
    struct utimbuf times;

    times.modtime = statb.st_mtime;
    times.actime = statb.st_atime;
    utime (include_filename, &times);
    }
return 0;
}
Ejemplo n.º 25
0
/*  Parse the input file and update the global symbol table and macro table,
 *  output the stripped file contents to devices if OUTFILE is not nil.
 *
 *  Returns a pointer to the error messages on failure, or nil on success.
 */
bool Parser::DoFile(InternalTables *intab, size_t num_preprocessors, File *infile, ParserContext *ctx)
{
	bool ignored;
	FILE *out_fp;
	bool retval = false;
	CC_STRING bak_fname, out_fname;
	struct stat    stb;
	struct utimbuf utb;

	if(ctx) {
		ignored = ctx->check_ignore(infile->name);
		if( ignored && ! has_dep_file() )
			return true;
	} else
		ignored = false;

	if( stat(infile->name, &stb) == 0 ) {
		utb.actime  = stb.st_atime;
		utb.modtime = stb.st_mtime;
	}
	if( ! infile->Open() ) {
		errmsg.Format("Cannot open \"%s\" for reading\n");
		return false;
	}

	out_fp = NULL;

	if(ctx != NULL && ctx->outfile != ParserContext::OF_NULL ) {
		if( ctx->outfile == ParserContext::OF_STDOUT )
			out_fp = stdout;
		else {
#if SANITY_CHECK
			assert( ! ctx->baksuffix.isnull() );
#endif
			if( ctx->baksuffix[0] != ParserContext::MAGIC_CHAR )
				bak_fname = infile->name + ctx->baksuffix;
			else
				out_fname = infile->name;

			int fd;
			char tmp_outfile[32];
			strcpy(tmp_outfile, "@cl@-XXXXXX");
			fd = mkstemp(tmp_outfile);
			if( fd < 0 ) {
				errmsg.Format("Cannot open \"%s\" for writing\n", tmp_outfile);
				infile->Close();
				return false;
			}
			out_fp = fdopen(fd, "wb");
			out_fname = tmp_outfile;
		}
	}

	if(ctx == NULL)
		memset(writers, 0, sizeof(writers));
	else {
		writers[VCH_CL] = NULL;
		if(!ctx->of_array[VCH_DEP].isnull())
			writers[VCH_DEP] = gvar_file_writers[VCH_DEP];
		if(!ctx->of_array[VCH_CV].isnull())
			writers[VCH_CV] = gvar_file_writers[VCH_CV];
	}

	if( num_preprocessors >= COUNT_OF(Parser::preprocessors) )
		num_preprocessors  = COUNT_OF(Parser::preprocessors);
	Reset(intab, num_preprocessors, ctx);

	if(has_dep_file())
		AddDependency("", infile->name);

	PushIncludedFile(infile, out_fp, COUNT_OF(Parser::preprocessors), false, conditionals.size());

	if(ctx != NULL) {
		GetCmdLineIncludeFiles(ctx->imacro_files, 2);
		GetCmdLineIncludeFiles(ctx->include_files, COUNT_OF(preprocessors));
	}

	if( ! RunEngine(0) )
		goto error;

	SaveDepInfo(deptext);
	if( conditionals.size() != 0 )
		errmsg = "Unmatched #if";
	else
		retval = true;

error:
	if(!retval) {
		if(included_files.size() > 0) {
			CC_STRING tmp;
			tmp.Format("%s:%u:  %s\n%s\n", GetCurrentFileName().c_str(), GetCurrentLineNumber(), pline.from.c_str(), GetError());
			errmsg = tmp;
		}
		#if 0
		IncludedFile *ilevel;
		while(included_files.size() > 0) {
			ilevel = PopIncludedFile();
			if(infile != ilevel->ifile)
				delete ilevel;
		}
		#endif
	}

	if(out_fp != NULL && out_fp != stdout)
		fclose(out_fp);

	if( retval && ctx != NULL && ! ignored ) {
		CC_STRING semname;
		sem_t *sem;

		semname = MakeSemaName(infile->name);
		sem = sem_open(semname.c_str(), O_CREAT, 0666, 1);
		sem_wait(sem);

		if( ! bak_fname.isnull() )
			rename(infile->name, bak_fname);
		if( ! out_fname.isnull() ) {
			rename(out_fname, infile->name);
			utime(infile->name.c_str(), &utb);
		}

		sem_post(sem);
		sem_unlink(semname.c_str());
	} else if( ! out_fname.isnull() )
		unlink(out_fname.c_str());

	return retval;
}
Ejemplo n.º 26
0
Archivo: work.cpp Proyecto: tfauck/upx
void do_one_file(const char *iname, char *oname)
{
    int r;
    struct stat st;
    memset(&st, 0, sizeof(st));
#if (HAVE_LSTAT)
    r = lstat(iname, &st);
#else
    r = stat(iname, &st);
#endif
    if (r != 0)
    {
        if (errno == ENOENT)
            throw FileNotFoundException(iname, errno);
        else
            throwIOException(iname, errno);
    }
    if (!(S_ISREG(st.st_mode)))
        throwIOException("not a regular file -- skipped");
#if defined(__unix__)
    // no special bits may be set
    if ((st.st_mode & (S_ISUID | S_ISGID | S_ISVTX)) != 0)
        throwIOException("file has special permissions -- skipped");
#endif
    if (st.st_size <= 0)
        throwIOException("empty file -- skipped");
    if (st.st_size < 512)
        throwIOException("file is too small -- skipped");
    if (!mem_size_valid_bytes(st.st_size))
        throwIOException("file is too large -- skipped");
    if ((st.st_mode & S_IWUSR) == 0)
    {
        bool skip = true;
        if (opt->output_name)
            skip = false;
        else if (opt->to_stdout)
            skip = false;
        else if (opt->backup)
            skip = false;
        if (skip)
            throwIOException("file is write protected -- skipped");
    }

    InputFile fi;
    fi.st = st;
    fi.sopen(iname, O_RDONLY | O_BINARY, SH_DENYWR);

#if (USE_FTIME)
    struct ftime fi_ftime;
    memset(&fi_ftime, 0, sizeof(fi_ftime));
    if (opt->preserve_timestamp)
    {
        if (getftime(fi.getFd(), &fi_ftime) != 0)
            throwIOException("cannot determine file timestamp");
    }
#endif

    // open output file
    OutputFile fo;
    if (opt->cmd == CMD_COMPRESS || opt->cmd == CMD_DECOMPRESS)
    {
        if (opt->to_stdout)
        {
            if (!fo.openStdout(1, opt->force ? true : false))
                throwIOException("data not written to a terminal; Use '-f' to force.");
        }
        else
        {
            char tname[ACC_FN_PATH_MAX+1];
            if (opt->output_name)
                strcpy(tname,opt->output_name);
            else
            {
                if (!maketempname(tname, sizeof(tname), iname, ".upx"))
                    throwIOException("could not create a temporary file name");
            }
            if (opt->force >= 2)
            {
#if (HAVE_CHMOD)
                r = chmod(tname, 0777);
                IGNORE_ERROR(r);
#endif
                r = unlink(tname);
                IGNORE_ERROR(r);
            }
            int flags = O_CREAT | O_WRONLY | O_BINARY;
            if (opt->force)
                flags |= O_TRUNC;
            else
                flags |= O_EXCL;
            int shmode = SH_DENYWR;
#if defined(__MINT__)
            flags |= O_TRUNC;
            shmode = O_DENYRW;
#endif
            // cannot rely on open() because of umask
            //int omode = st.st_mode | 0600;
            int omode = 0600;
            if (!opt->preserve_mode)
                omode = 0666;
            fo.sopen(tname,flags,shmode,omode);
            // open succeeded - now set oname[]
            strcpy(oname,tname);
        }
    }

    // handle command
    PackMaster pm(&fi, opt);
    if (opt->cmd == CMD_COMPRESS)
        pm.pack(&fo);
    else if (opt->cmd == CMD_DECOMPRESS)
        pm.unpack(&fo);
    else if (opt->cmd == CMD_TEST)
        pm.test();
    else if (opt->cmd == CMD_LIST)
        pm.list();
    else if (opt->cmd == CMD_FILEINFO)
        pm.fileInfo();
    else
        throwInternalError("invalid command");

    // copy time stamp
    if (opt->preserve_timestamp && oname[0] && fo.isOpen())
    {
#if (USE_FTIME)
        r = setftime(fo.getFd(), &fi_ftime);
        IGNORE_ERROR(r);
#elif (USE__FUTIME)
        struct _utimbuf u;
        u.actime = st.st_atime;
        u.modtime = st.st_mtime;
        r = _futime(fo.getFd(), &u);
        IGNORE_ERROR(r);
#endif
    }

    // close files
    fo.closex();
    fi.closex();

    // rename or delete files
    if (oname[0] && !opt->output_name)
    {
        // FIXME: .exe or .cof etc.
        if (!opt->backup)
        {
#if (HAVE_CHMOD)
            r = chmod(iname, 0777);
            IGNORE_ERROR(r);
#endif
            File::unlink(iname);
        }
        else
        {
            // make backup
            char bakname[ACC_FN_PATH_MAX+1];
            if (!makebakname(bakname, sizeof(bakname), iname))
                throwIOException("could not create a backup file name");
            File::rename(iname,bakname);
        }
        File::rename(oname,iname);
    }

    // copy file attributes
    if (oname[0])
    {
        oname[0] = 0;
        const char *name = opt->output_name ? opt->output_name : iname;
        UNUSED(name);
#if (USE_UTIME)
        // copy time stamp
        if (opt->preserve_timestamp)
        {
            struct utimbuf u;
            u.actime = st.st_atime;
            u.modtime = st.st_mtime;
            r = utime(name, &u);
            IGNORE_ERROR(r);
        }
#endif
#if (HAVE_CHMOD)
        // copy permissions
        if (opt->preserve_mode)
        {
            r = chmod(name, st.st_mode);
            IGNORE_ERROR(r);
        }
#endif
#if (HAVE_CHOWN)
        // copy the ownership
        if (opt->preserve_ownership)
        {
            r = chown(name, st.st_uid, st.st_gid);
            IGNORE_ERROR(r);
        }
#endif
    }

    UiPacker::uiConfirmUpdate();
}
Ejemplo n.º 27
0
void test_file(void)
{
    int fd, i, len, ret;
    uint8_t buf[FILE_BUF_SIZE];
    uint8_t buf2[FILE_BUF_SIZE];
    uint8_t buf3[FILE_BUF_SIZE];
    char cur_dir[1024];
    struct stat st;
    struct utimbuf tbuf;
    struct iovec vecs[2];
    DIR *dir;
    struct dirent *de;

    /* clean up, just in case */
    unlink(TESTPATH "/file1");
    unlink(TESTPATH "/file2");
    unlink(TESTPATH "/file3");
    rmdir(TESTPATH);

    if (getcwd(cur_dir, sizeof(cur_dir)) == NULL)
        error("getcwd");

    chk_error(mkdir(TESTPATH, 0755));

    chk_error(chdir(TESTPATH));

    /* open/read/write/close/readv/writev/lseek */

    fd = chk_error(open("file1", O_WRONLY | O_TRUNC | O_CREAT, 0644));
    for(i=0; i < FILE_BUF_SIZE; i++)
        buf[i] = i;
    len = chk_error(write(fd, buf, FILE_BUF_SIZE / 2));
    if (len != (FILE_BUF_SIZE / 2))
        error("write");
    vecs[0].iov_base = buf + (FILE_BUF_SIZE / 2);
    vecs[0].iov_len = 16;
    vecs[1].iov_base = buf + (FILE_BUF_SIZE / 2) + 16;
    vecs[1].iov_len = (FILE_BUF_SIZE / 2) - 16;
    len = chk_error(writev(fd, vecs, 2));
    if (len != (FILE_BUF_SIZE / 2))
        error("writev");
    chk_error(close(fd));

    chk_error(rename("file1", "file2"));

    fd = chk_error(open("file2", O_RDONLY));

    len = chk_error(read(fd, buf2, FILE_BUF_SIZE));
    if (len != FILE_BUF_SIZE)
        error("read");
    if (memcmp(buf, buf2, FILE_BUF_SIZE) != 0)
        error("memcmp");

#define FOFFSET 16
    ret = chk_error(lseek(fd, FOFFSET, SEEK_SET));
    if (ret != 16)
        error("lseek");
    vecs[0].iov_base = buf3;
    vecs[0].iov_len = 32;
    vecs[1].iov_base = buf3 + 32;
    vecs[1].iov_len = FILE_BUF_SIZE - FOFFSET - 32;
    len = chk_error(readv(fd, vecs, 2));
    if (len != FILE_BUF_SIZE - FOFFSET)
        error("readv");
    if (memcmp(buf + FOFFSET, buf3, FILE_BUF_SIZE - FOFFSET) != 0)
        error("memcmp");

    chk_error(close(fd));

    /* access */
    chk_error(access("file2", R_OK));

    /* stat/chmod/utime/truncate */

    chk_error(chmod("file2", 0600));
    tbuf.actime = 1001;
    tbuf.modtime = 1000;
    chk_error(truncate("file2", 100));
    chk_error(utime("file2", &tbuf));
    chk_error(stat("file2", &st));
    if (st.st_size != 100)
        error("stat size");
    if (!S_ISREG(st.st_mode))
        error("stat mode");
    if ((st.st_mode & 0777) != 0600)
        error("stat mode2");
    if (st.st_atime != 1001 ||
            st.st_mtime != 1000)
        error("stat time");

    chk_error(stat(TESTPATH, &st));
    if (!S_ISDIR(st.st_mode))
        error("stat mode");

    /* fstat */
    fd = chk_error(open("file2", O_RDWR));
    chk_error(ftruncate(fd, 50));
    chk_error(fstat(fd, &st));
    chk_error(close(fd));

    if (st.st_size != 50)
        error("stat size");
    if (!S_ISREG(st.st_mode))
        error("stat mode");

    /* symlink/lstat */
    chk_error(symlink("file2", "file3"));
    chk_error(lstat("file3", &st));
    if (!S_ISLNK(st.st_mode))
        error("stat mode");

    /* getdents */
    dir = opendir(TESTPATH);
    if (!dir)
        error("opendir");
    len = 0;
    for(;;) {
        de = readdir(dir);
        if (!de)
            break;
        if (strcmp(de->d_name, ".") != 0 &&
                strcmp(de->d_name, "..") != 0 &&
                strcmp(de->d_name, "file2") != 0 &&
                strcmp(de->d_name, "file3") != 0)
            error("readdir");
        len++;
    }
    closedir(dir);
    if (len != 4)
        error("readdir");

    chk_error(unlink("file3"));
    chk_error(unlink("file2"));
    chk_error(chdir(cur_dir));
    chk_error(rmdir(TESTPATH));
}
Ejemplo n.º 28
0
int copy_file(const char *source, const char *dest, int flags)
{
	struct stat source_stat;
	struct stat dest_stat;
	int dest_exists = 0;
	int status = 0;

	if ((!(flags & FILEUTILS_DEREFERENCE) &&
			lstat(source, &source_stat) < 0) ||
			((flags & FILEUTILS_DEREFERENCE) &&
			 stat(source, &source_stat) < 0)) {
		bb_perror_msg("%s", source);
		return -1;
	}

	if (lstat(dest, &dest_stat) < 0) {
		if (errno != ENOENT) {
			bb_perror_msg("unable to stat `%s'", dest);
			return -1;
		}
	} else {
		if (source_stat.st_dev == dest_stat.st_dev &&
			source_stat.st_ino == dest_stat.st_ino)
		{
			bb_error_msg("`%s' and `%s' are the same file", source, dest);
			return -1;
		}
		dest_exists = 1;
	}

	if (S_ISDIR(source_stat.st_mode)) {
		DIR *dp;
		struct dirent *d;
		mode_t saved_umask = 0;

		if (!(flags & FILEUTILS_RECUR)) {
			bb_error_msg("%s: omitting directory", source);
			return -1;
		}

		/* Create DEST.  */
		if (dest_exists) {
			if (!S_ISDIR(dest_stat.st_mode)) {
				bb_error_msg("`%s' is not a directory", dest);
				return -1;
			}
		} else {
			mode_t mode;
			saved_umask = umask(0);

			mode = source_stat.st_mode;
			if (!(flags & FILEUTILS_PRESERVE_STATUS))
				mode = source_stat.st_mode & ~saved_umask;
			mode |= S_IRWXU;

			if (mkdir(dest, mode) < 0) {
				umask(saved_umask);
				bb_perror_msg("cannot create directory `%s'", dest);
				return -1;
			}

			umask(saved_umask);
		}

		/* Recursively copy files in SOURCE.  */
		if ((dp = bb_opendir(source)) == NULL) {
			status = -1;
			goto preserve_status;
		}

		while ((d = readdir(dp)) != NULL) {
			char *new_source, *new_dest;

			new_source = concat_subpath_file(source, d->d_name);
			if(new_source == NULL)
				continue;
			new_dest = concat_path_file(dest, d->d_name);
			if (copy_file(new_source, new_dest, flags) < 0)
				status = -1;
			free(new_source);
			free(new_dest);
		}
		/* closedir have only EBADF error, but "dp" not changes */
		closedir(dp);

		if (!dest_exists &&
				chmod(dest, source_stat.st_mode & ~saved_umask) < 0) {
			bb_perror_msg("unable to change permissions of `%s'", dest);
			status = -1;
		}
	} else if (S_ISREG(source_stat.st_mode) ||
		   (S_ISLNK(source_stat.st_mode) && (flags & FILEUTILS_DEREFERENCE)))
	{
		int src_fd;
		int dst_fd;
		if (ENABLE_FEATURE_PRESERVE_HARDLINKS) {
			char *link_name;

			if (!(flags & FILEUTILS_DEREFERENCE) &&
					is_in_ino_dev_hashtable(&source_stat, &link_name)) {
				if (link(link_name, dest) < 0) {
					bb_perror_msg("unable to link `%s'", dest);
					return -1;
				}

				return 0;
			}
			add_to_ino_dev_hashtable(&source_stat, dest);
		}
		src_fd = open(source, O_RDONLY);
		if (src_fd == -1) {
			bb_perror_msg("unable to open `%s'", source);
			return(-1);
		}

		if (dest_exists) {
			if (flags & FILEUTILS_INTERACTIVE) {
				fprintf(stderr, "%s: overwrite `%s'? ", bb_applet_name, dest);
				if (!bb_ask_confirmation()) {
					close (src_fd);
					return 0;
				}
			}

			dst_fd = open(dest, O_WRONLY|O_TRUNC);
			if (dst_fd == -1) {
				if (!(flags & FILEUTILS_FORCE)) {
					bb_perror_msg("unable to open `%s'", dest);
					close(src_fd);
					return -1;
				}

				if (unlink(dest) < 0) {
					bb_perror_msg("unable to remove `%s'", dest);
					close(src_fd);
					return -1;
				}

				goto dest_removed;
			}
		} else {
dest_removed:
			dst_fd = open(dest, O_WRONLY|O_CREAT, source_stat.st_mode);
			if (dst_fd == -1) {
				bb_perror_msg("unable to open `%s'", dest);
				close(src_fd);
				return(-1);
			}
		}

		if (bb_copyfd_eof(src_fd, dst_fd) == -1)
			status = -1;

		if (close(dst_fd) < 0) {
			bb_perror_msg("unable to close `%s'", dest);
			status = -1;
		}

		if (close(src_fd) < 0) {
			bb_perror_msg("unable to close `%s'", source);
			status = -1;
		}
	} else if (S_ISBLK(source_stat.st_mode) || S_ISCHR(source_stat.st_mode) ||
	    S_ISSOCK(source_stat.st_mode) || S_ISFIFO(source_stat.st_mode) ||
	    S_ISLNK(source_stat.st_mode)) {

		if (dest_exists) {
			if((flags & FILEUTILS_FORCE) == 0) {
				fprintf(stderr, "`%s' exists\n", dest);
				return -1;
			}
			if(unlink(dest) < 0) {
				bb_perror_msg("unable to remove `%s'", dest);
				return -1;
			}
		}
		if (S_ISFIFO(source_stat.st_mode)) {
			if (mkfifo(dest, source_stat.st_mode) < 0) {
				bb_perror_msg("cannot create fifo `%s'", dest);
				return -1;
			}
		} else if (S_ISLNK(source_stat.st_mode)) {
			char *lpath;

			lpath = xreadlink(source);
			if (symlink(lpath, dest) < 0) {
				bb_perror_msg("cannot create symlink `%s'", dest);
				return -1;
			}
			free(lpath);

			if (flags & FILEUTILS_PRESERVE_STATUS)
				if (lchown(dest, source_stat.st_uid, source_stat.st_gid) < 0)
					bb_perror_msg("unable to preserve ownership of `%s'", dest);

			return 0;

		} else {
			if (mknod(dest, source_stat.st_mode, source_stat.st_rdev) < 0) {
				bb_perror_msg("unable to create `%s'", dest);
				return -1;
			}
		}
	} else {
		bb_error_msg("internal error: unrecognized file type");
		return -1;
	}

preserve_status:

	if (flags & FILEUTILS_PRESERVE_STATUS) {
		struct utimbuf times;
		char *msg="unable to preserve %s of `%s'";

		times.actime = source_stat.st_atime;
		times.modtime = source_stat.st_mtime;
		if (utime(dest, &times) < 0)
			bb_perror_msg(msg, "times", dest);
		if (chown(dest, source_stat.st_uid, source_stat.st_gid) < 0) {
			source_stat.st_mode &= ~(S_ISUID | S_ISGID);
			bb_perror_msg(msg, "ownership", dest);
		}
		if (chmod(dest, source_stat.st_mode) < 0)
			bb_perror_msg(msg, "permissions", dest);
	}

	return status;
}
Ejemplo n.º 29
0
Archivo: ptic.c Proyecto: bbs-io/mbse
/*
 * Return values:
 * 0 - Success
 * 1 - Some error
 * 2 - Orphaned tic
 */
int ProcessTic(fa_list **sbl, orphans **opl)
{
    int		    First, Listed = FALSE, DownLinks = 0, MustRearc = FALSE;
    int		    UnPacked = FALSE, IsArchive = FALSE, rc, i, j, k;
    char	    *Temp, *unarc = NULL, *cmd = NULL;
    char	    temp1[PATH_MAX], temp2[PATH_MAX], sbe[24], TDesc[1024];
    unsigned int    crc, crc2, Kb;
    sysconnect	    Link;
    FILE	    *fp;
    struct utimbuf  ut;
    int		    BBS_Imp = FALSE, DidBanner = FALSE;
    faddr	    *p_from;
    qualify	    *qal = NULL, *tmpq;
    orphans	    *topl;

    if (TIC.TicIn.PathError) {
	WriteError("Our Aka is in the path");
	tic_bad++;
	return 1;
    }

    Temp = calloc(PATH_MAX, sizeof(char));

    if (!do_quiet) {
	mbse_colour(LIGHTGREEN, BLACK);
	printf("Checking  \b\b\b\b\b\b\b\b\b\b");
	fflush(stdout);
    }

    if (TIC.Orphaned) {
	fill_orphans(opl, TIC.TicName, TIC.TicIn.Area, TIC.TicIn.File, TRUE, FALSE);
	Syslog('+', "File not in inbound: %s", TIC.TicIn.File);
	free(Temp);
	return 2;
    }

    snprintf(Temp, PATH_MAX, "%s/%s", TIC.Inbound, TIC.TicIn.File);
    crc = file_crc(Temp, CFG.slow_util && do_quiet);
    TIC.FileSize = file_size(Temp);
    TIC.FileDate = file_time(Temp);

    if (TIC.TicIn.Size) {
	if (TIC.TicIn.Size != TIC.FileSize)
	    WriteError("Size is %ld, expected %ld", TIC.FileSize, TIC.TicIn.Size);
    } else {
	/*
	 * No filesize in TIC file, add filesize.
	 */
	TIC.TicIn.Size = TIC.FileSize;
    }

    if (TIC.Crc_Int) {
	if (crc != TIC.Crc_Int) {
	    Syslog('!', "CRC: expected %08lX, the file is %08lX", TIC.Crc_Int, crc);
	    fill_orphans(opl, TIC.TicName, TIC.TicIn.Area, TIC.TicIn.File, FALSE, TRUE);
	    if (check_crc) {
		Syslog('+', "Bad CRC, will check this ticfile later");
		free(Temp);
		return 1;
	    } else {
		Syslog('!', "CRC: error, recalculating crc");
		ReCalcCrc(Temp);
	    }
	}
    } else {
	Syslog('+', "CRC: missing, calculating CRC");
	ReCalcCrc(Temp);
    }

    /*
     * Load and check the .TIC area.
     */
    if (!SearchTic(TIC.TicIn.Area)) {
	UpdateNode();
	Syslog('f', "Unknown file area %s", TIC.TicIn.Area);
	p_from = fido2faddr(TIC.Aka);
	if (!create_ticarea(TIC.TicIn.Area, p_from)) {
	    Bad((char *)"Unknown file area %s", TIC.TicIn.Area);
	    free(Temp);
	    tidy_faddr(p_from);
	    return 1;
	}
	tidy_faddr(p_from);
	/*
	 * Try to load the .TIC area again.
	 */
	if (!SearchTic(TIC.TicIn.Area)) {
	    Bad((char *)"Reload of new created file area %s failed", TIC.TicIn.Area);
	    free(Temp);
	    return 1;
	}
    }

    if ((tic.Secure) && (!TIC.TicIn.Hatch)) {
	First = TRUE;
	while (GetTicSystem(&Link, First)) {
	    First = FALSE;
	    if (Link.aka.zone) {
		if ((Link.aka.zone == TIC.Aka.zone) && (Link.aka.net  == TIC.Aka.net) &&
		    (Link.aka.node == TIC.Aka.node) && (Link.aka.point== TIC.Aka.point) && (Link.receivefrom)) 
		    Listed = TRUE;
	    }
	}
	if (!Listed) {
	    Bad((char *)"%s NOT connected to %s", aka2str(TIC.Aka), TIC.TicIn.Area);
	    free(Temp);
	    return 1;
	}
    }

    if ((!SearchNode(TIC.Aka)) && (!TIC.TicIn.Hatch)) {
	Bad((char *)"%s NOT known", aka2str(TIC.Aka));
	free(Temp);
	return 1;
    }

    if (!TIC.TicIn.Hatch) {
	if (strcasecmp(TIC.TicIn.Pw, nodes.Fpasswd)) {
	    Bad((char *)"Pwd error, got %s, expected %s", TIC.TicIn.Pw, nodes.Fpasswd);
	    free(Temp);
	    return 1;
	}
    } else {
	if (strcasecmp(TIC.TicIn.Pw, CFG.hatchpasswd)) {
	    Bad((char *)"Password error in local Hatch");
	    WriteError("WARNING: it might be a Trojan in your inbound");
	    free(Temp);
	    return 1;
	}
    }

    if (Magic_DeleteFile()) {
	snprintf(temp1, PATH_MAX, "%s/%s", TIC.Inbound, TIC.TicName);
	file_rm(temp1);
	Syslog('+', "Deleted file %s", temp1);
	file_rm(Temp);
	free(Temp);
	return 0;
    }


    if (Magic_MoveFile()) {
	if (!SearchTic(TIC.TicIn.Area)) {
	    Bad((char *)"Unknown Area: %s", TIC.TicIn.Area);
	    free(Temp);
	    return 1;
	}
    }

    strncpy(T_File.Echo, tic.Name, 20);
    strncpy(T_File.Group, tic.Group, 12);
    TIC.KeepNum = tic.KeepLatest;

    Magic_Keepnum();

    if (!tic.FileArea) {
	Syslog('+', "Passthru TIC area!");
	strcpy(TIC.BBSpath, CFG.ticout);
	strcpy(TIC.BBSdesc, tic.Comment);
    } else {
	snprintf(Temp, PATH_MAX, "%s/etc/fareas.data", getenv("MBSE_ROOT"));
	if ((fp = fopen(Temp, "r")) == NULL) {
	    WriteError("Can't access fareas.data area: %ld", tic.FileArea);
	    free(Temp);
	    return 1;
	}
	fread(&areahdr, sizeof(areahdr), 1, fp);
	if (fseek(fp, ((tic.FileArea -1) * areahdr.recsize) + areahdr.hdrsize, SEEK_SET)) {
	    fclose(fp);
	    WriteError("Can't seek area %ld in fareas.data", tic.FileArea);
	    free(Temp);
	    return 1;
	}
	if (fread(&area, areahdr.recsize, 1, fp) != 1) {
	    fclose(fp);
	    WriteError("Can't read area %ld in fareas.data", tic.FileArea);
	    free(Temp);
	    return 1;
	}
	fclose(fp);
	strcpy(TIC.BBSpath, area.Path);
	strcpy(TIC.BBSdesc, area.Name);

	/*
	 * If the File area has a special announce group, change
	 * the group to that name.
	 */
	if (strlen(area.NewGroup))
	    strncpy(T_File.Group, area.NewGroup, 12);
    }
    strncpy(T_File.Comment, tic.Comment, 55);

    /*
     * Check if the destination area really exists, it may be that
     * the area is not linked to an existing BBS area.
     */
    if (tic.FileArea && access(TIC.BBSpath, W_OK)) {
	WriteError("No write access to \"%s\"", TIC.BBSpath);
	Bad((char *)"Dest directory not available");
	free(Temp);
	return 1;
    }

    if ((tic.DupCheck) && (check_dupe)) {
	snprintf(Temp, PATH_MAX, "%s%s", TIC.TicIn.Area, TIC.TicIn.Crc);
	crc2 = 0xffffffff;
	crc2 = upd_crc32(Temp, crc2, strlen(Temp));
	if (CheckDupe(crc2, D_FILEECHO, CFG.tic_dupes)) {
	    Bad((char *)"Duplicate file");
	    tic_dup++;
	    free(Temp);
	    return 1;
	}
    }

    /*
     * Count the actual downlinks for this area and build the list of
     * systems qualified to receive this file.
     */
    First = TRUE;
    while (GetTicSystem(&Link, First)) {
	First = FALSE;
	if ((Link.aka.zone) && (Link.sendto) && (!Link.pause)) {
	    DownLinks++;
	    p_from = fido2faddr(Link.aka);
	    if (TIC.TicIn.Hatch) {
		fill_qualify(&qal, Link.aka, FALSE, in_list(p_from, sbl, TRUE));
	    } else {
		fill_qualify(&qal, Link.aka, ((TIC.Aka.zone == Link.aka.zone) &&
			(TIC.Aka.net == Link.aka.net) && (TIC.Aka.node == Link.aka.node) &&
			(TIC.Aka.point == Link.aka.point)), in_list(p_from, sbl, TRUE));
	    }
	    tidy_faddr(p_from);
	}
    }

    T_File.Size = TIC.FileSize;
    T_File.SizeKb = TIC.FileSize / 1024;

    /*
     * Update the uplink's counters.
     */
    Kb = TIC.FileSize / 1024;
    if (SearchNode(TIC.Aka)) {
	StatAdd(&nodes.FilesRcvd, 1L);
	StatAdd(&nodes.F_KbRcvd, Kb);
	UpdateNode();
	SearchNode(TIC.Aka);
    }

    /*
     * Update the fileecho and group counters.
     */
    StatAdd(&fgroup.Files, 1L);
    StatAdd(&fgroup.KBytes, Kb);
    fgroup.LastDate = time(NULL);
    StatAdd(&tic.Files, 1L);
    StatAdd(&tic.KBytes, Kb);
    tic.LastAction = time(NULL);
    UpdateTic();

    if (!do_quiet) {
	printf("Unpacking \b\b\b\b\b\b\b\b\b\b");
	fflush(stdout);
    }

    /*
     * Check if this is an archive, and if so, which compression method
     * is used for this file.
     */
    if (strlen(tic.Convert) || tic.FileId || tic.ConvertAll || strlen(tic.Banner)) {
	/*
	 * Create tmp workdir
	 */
	if (create_tmpwork()) {
	    free(Temp);
	    tidy_qualify(&qal);
	    return 1;
	}

	if ((unarc = unpacker(TIC.TicIn.File)) == NULL)
	    Syslog('+', "Unknown archive format %s", TIC.TicIn.File);
	else {
	    IsArchive = TRUE;
	    if ((strlen(tic.Convert) && (strcmp(unarc, tic.Convert) == 0)) || (tic.ConvertAll))
		MustRearc = TRUE;
	}
    }

    /*
     * Copy the file if there are downlinks and we send the 
     * original file, but want to rearc it for ourself, or if
     * it's a passthru area.
     */
    if (((tic.SendOrg) && (MustRearc || strlen(tic.Banner))) || (!tic.FileArea)) {
	snprintf(temp1, PATH_MAX, "%s/%s", TIC.Inbound, TIC.TicIn.File);
	snprintf(temp2, PATH_MAX, "%s/%s", CFG.ticout, TIC.TicIn.File);
	if ((rc = file_cp(temp1, temp2) == 0)) {
	    TIC.SendOrg = TRUE;
	} else {
	    WriteError("Copy %s to %s failed: %s", temp1, temp2, strerror(rc));
	}
    }

    if (MustRearc && IsArchive) {

	snprintf(temp2, PATH_MAX, "%s/tmp/arc%d", getenv("MBSE_ROOT"), (int)getpid());
	if (!checkspace(temp2, TIC.TicIn.File, UNPACK_FACTOR)) {
	    Bad((char *)"Not enough free diskspace left");
	    free(Temp);
	    tidy_qualify(&qal);
	    clean_tmpwork();
	    return 1;
	}

	if (chdir(temp2) != 0) {
	    WriteError("$Can't change to %s", temp2);
	    free(Temp);
	    tidy_qualify(&qal);
	    clean_tmpwork();
	    return 1;
	}

	if (!getarchiver(unarc)) {
	    WriteError("Can't get archiver for %s", unarc);
	    chdir(TIC.Inbound);
	    free(Temp);
	    tidy_qualify(&qal);
	    clean_tmpwork();
	    return 1;
	}

	if (strlen(archiver.funarc) == 0) {
	    Syslog('!', "No unarc command available");
	} else {
	    cmd = xstrcpy(archiver.funarc);
	    snprintf(temp1, PATH_MAX, "%s/%s", TIC.Inbound, TIC.TicIn.File);
	    if (execute_str(cmd, temp1, (char *)NULL, (char *)"/dev/null", (char *)"/dev/null", (char *)"/dev/null") == 0) {
		UnPacked = TRUE;
	    } else {
		chdir(TIC.Inbound);
		Bad((char *)"Archive maybe corrupt");
		free(Temp);
		clean_tmpwork();
		return 1;
	    }
	    free(cmd);
	}
    }

    /*
     * Scan file for viri.
     */
    if (tic.VirScan) {

	snprintf(temp1, PATH_MAX, "%s/%s", TIC.Inbound, TIC.TicIn.File);

	if (!do_quiet) {
	    printf("Virscan   \b\b\b\b\b\b\b\b\b\b");
	    fflush(stdout);
	}

	if (VirScanFile(temp1)) {
	    chdir(TIC.Inbound);
	    Bad((char *)"Possible virus found!");
	    free(Temp);
	    tidy_qualify(&qal);
	    clean_tmpwork();
	    return 1;
	}

	if (!do_quiet) {
	    printf("Checking  \b\b\b\b\b\b\b\b\b\b");
	    fflush(stdout);
	}

    }

    if (tic.FileId && tic.FileArea && IsArchive) {
	if (UnPacked) {
	    snprintf(temp1, PATH_MAX, "%s/tmp/arc%d", getenv("MBSE_ROOT"), (int)getpid());
	    snprintf(Temp, PATH_MAX, "FILE_ID.DIZ");
	    if (getfilecase(temp1, Temp)) {
		Syslog('f', "Found %s", Temp);
		snprintf(temp1, PATH_MAX, "%s/tmp/arc%d/%s", getenv("MBSE_ROOT"), (int)getpid(), Temp);
		snprintf(temp2, PATH_MAX, "%s/tmp/FILE_ID.DIZ", getenv("MBSE_ROOT"));
	    } else {
		Syslog('f', "Didn't find a FILE_ID.DIZ");
	    }
	} else {
	    if (!getarchiver(unarc)) {
		chdir(TIC.Inbound);
	    } else {
		cmd = xstrcpy(archiver.iunarc);

		if (cmd == NULL) {
		    WriteError("No unarc command available");
		} else {
		    snprintf(temp1, PATH_MAX, "%s/tmp", getenv("MBSE_ROOT"));
		    chdir(temp1);
		    snprintf(temp1, PATH_MAX, "%s/%s FILE_ID.DIZ", TIC.Inbound, TIC.TicIn.File);
		    if (execute_str(cmd, temp1, (char *)NULL, (char *)"/dev/null", (char *)"/dev/null", (char *)"/dev/null")) {
			snprintf(temp1, PATH_MAX, "%s/%s file_id.diz", TIC.Inbound, TIC.TicIn.File);
			execute_str(cmd, temp1, (char *)NULL, (char *)"/dev/null", (char *)"/dev/null", (char *)"/dev/null");
		    }
		    free(cmd);
		}
	    } /* if getarchiver */
	} /* if not unpacked */
    } /* if need FILE_ID.DIZ and not passthru */

    /*
     * Create internal file description, priority is FILE_ID.DIZ,
     * 2nd LDesc, and finally the standard description.
     */
    if (!Get_File_Id()) {
	if (TIC.TicIn.TotLDesc > 2) {
	    for (i = 0; i < TIC.TicIn.TotLDesc; i++) {
		strncpy(TIC.File_Id[i], TIC.TicIn.LDesc[i], 48);
	    }
	    TIC.File_Id_Ct = TIC.TicIn.TotLDesc;
	} else {
	    /*
	     * Format the description line (max 255 chars) in parts of 48 characters.
	     */
	    if (strlen(TIC.TicIn.Desc) <= 48) {
		strcpy(TIC.File_Id[0], TIC.TicIn.Desc);
		TIC.File_Id_Ct++;
	    } else {
		memset(&TDesc, 0, sizeof(TDesc));
		strcpy(TDesc, TIC.TicIn.Desc);
		while (strlen(TDesc) > 48) {
		    j = 48;
		    while ((TDesc[j] != ' ') && (j > 0))
			j--;
		    if (j == 0) {
			Syslog('f', "Panic, no spaces");
			j = 47;
		    }
		    strncpy(TIC.File_Id[TIC.File_Id_Ct], TDesc, j);
		    Syslog('f', "%2d/%2d: \"%s\"", TIC.File_Id_Ct, j, TIC.File_Id[TIC.File_Id_Ct]);
		    TIC.File_Id_Ct++;
		    k = strlen(TDesc);
		    j++; /* Correct space */
		    for (i = 0; i <= k; i++, j++)
			TDesc[i] = TDesc[j];
		    if (TIC.File_Id_Ct == 23)
			break;
		}
		strncpy(TIC.File_Id[TIC.File_Id_Ct], TDesc, 48);
		Syslog('f', "%2d/%2d: \"%s\"", TIC.File_Id_Ct, strlen(TIC.File_Id[TIC.File_Id_Ct]), TIC.File_Id[TIC.File_Id_Ct]);
		TIC.File_Id_Ct++;
	    }
	}
    } /* not get FILE_ID.DIZ */

    /*
     * Now check if other (older) ticfiles point to this file,
     * if found mark it to purge later.
     */
    for (topl = *opl; topl; topl = topl->next) {
	if ((strcmp(topl->Area, TIC.TicIn.Area) == 0) && (strcmp(topl->FileName, TIC.TicIn.File) == 0)) {
	    topl->Purged = TRUE;
	}
    }

    /*
     * Rearc file if it is an unpacked archive.
     */
    if ((MustRearc) && (UnPacked) && (tic.FileArea)) {
	if (Rearc(tic.Convert)) {
	    /*
	     * Get new filesize for import and announce
	     */
	    snprintf(temp1, PATH_MAX, "%s/%s", TIC.Inbound, TIC.NewFile);
	    TIC.FileSize = file_size(temp1);
	    T_File.Size = TIC.FileSize;
	    T_File.SizeKb = TIC.FileSize / 1024;
	    /*
	     * Calculate the CRC if we must send the new archived file.
	     */
	    if (!TIC.SendOrg) {
		ReCalcCrc(temp1);
	    }
	} else {
	    WriteError("Rearc failed");
	} /* if Rearc() */
    }

    /*
     * Change banner if needed.
     */
    if ((strlen(tic.Banner)) && IsArchive) {
	cmd = xstrcpy(archiver.barc);
	if ((cmd == NULL) || (!strlen(cmd))) {
	    Syslog('+', "No banner command for %s", archiver.name);
	} else {
	    snprintf(temp1, PATH_MAX, "%s/%s", TIC.Inbound, TIC.NewFile);
	    snprintf(Temp, PATH_MAX, "%s/etc/%s", getenv("MBSE_ROOT"), tic.Banner);
	    if (execute_str(cmd, temp1, (char *)NULL, Temp, (char *)"/dev/null", (char *)"/dev/null")) {
		WriteError("Changing the banner failed");
	    } else {
		Syslog('+', "New banner %s", tic.Banner);
		TIC.FileSize = file_size(temp1);
		T_File.Size = TIC.FileSize;
		T_File.SizeKb = TIC.FileSize / 1024;
		ReCalcCrc(temp1);
		DidBanner = TRUE;
	    }
	}
    }
    clean_tmpwork();
    chdir(TIC.Inbound);

    /*
     * If the file is converted, we set the date of the original
     * received file as the file creation date.
     */
    snprintf(Temp, PATH_MAX, "%s/%s", TIC.Inbound, TIC.NewFile);
    if ((MustRearc || DidBanner) && CFG.ct_KeepDate) {
	if ((tic.Touch) && (tic.FileArea)) {
	    ut.actime = mktime(localtime(&TIC.FileDate));
	    ut.modtime = mktime(localtime(&TIC.FileDate));
	    utime(Temp, &ut);
	    Syslog('-', "Restamp filedate %s to %s", Temp, rfcdate(ut.modtime));
	}
    }
    /*
     * Now make sure the file timestamp is updated. The file may be restamped,
     * altered by banners etc.
     */
    TIC.FileDate = file_time(Temp);

    /*
     * If not passthru, import in the BBS.
     */
    if (tic.FileArea) {

	Syslog('+', "Import: %s (%s) Area: %s", TIC.NewFile, TIC.NewFullName, TIC.TicIn.Area);
	BBS_Imp = Add_BBS(&qal);

	if (!BBS_Imp) {
	    Bad((char *)"File Import Error");
	    free(Temp);
	    tidy_qualify(&qal);
	    clean_tmpwork();
	    return 1;
	}
    }

    chdir(TIC.Inbound);

    /*
     * Create file announce record
     */
    if (tic.FileArea) {
	if (strlen(TIC.TicIn.Magic))
	    magic_update(TIC.TicIn.Magic, TIC.NewFile);
	else
	    Magic_UpDateAlias();

	for (i = 0; i < TIC.File_Id_Ct; i++)
	    strncpy(T_File.LDesc[i], TIC.File_Id[i], 48);
	T_File.TotLdesc = TIC.File_Id_Ct;
	T_File.Announce = tic.Announce;
	strncpy(T_File.Name, TIC.NewFile, 12);
	strncpy(T_File.LName, TIC.NewFullName, 80);
	T_File.Fdate = TIC.FileDate;
	Add_ToBeRep(T_File);
    }

    if (TIC.SendOrg && !tic.FileArea) {
	/*
	 * If it's a passthru area we don't need the
	 * file in the inbound anymore so it can be
	 * deleted.
	 */
	snprintf(temp1, PATH_MAX, "%s/%s", TIC.Inbound, TIC.TicIn.File);
	if (file_rm(temp1) == 0)
	    Syslog('f', "Deleted %s", temp1);
    }

    if (DownLinks) {
	First = TRUE;

	/*
	 * Add all our system aka's to the seenby lines in the same zone,
	 * omit aka's already in the seenby list.
	 */
	for (i = 0; i < 39; i++) {
	    if (CFG.akavalid[i] && (tic.Aka.zone == CFG.aka[i].zone)) {
		p_from = fido2faddr(CFG.aka[i]);
		if (! in_list(p_from, sbl, TRUE)) {
		    if (CFG.aka[i].point)
			snprintf(sbe, 24, "%u:%u/%u.%u", CFG.aka[i].zone, CFG.aka[i].net, CFG.aka[i].node, CFG.aka[i].point);
		    else
			snprintf(sbe, 24, "%u:%u/%u", CFG.aka[i].zone, CFG.aka[i].net, CFG.aka[i].node);
		    fill_list(sbl, sbe, NULL);
		}
		tidy_faddr(p_from);
	    }
	}

	/*
	 * Add seen-by lines for all systems that will receive this file.
	 */
	for (tmpq = qal; tmpq; tmpq = tmpq->next) {
	    if (tmpq->send) {
		if (CFG.aka[i].point)
		    snprintf(sbe, 24, "%u:%u/%u.%u", tmpq->aka.zone, tmpq->aka.net, tmpq->aka.node, tmpq->aka.point);
		else
		    snprintf(sbe, 24, "%u:%u/%u", tmpq->aka.zone, tmpq->aka.net, tmpq->aka.node);
		fill_list(sbl, sbe, NULL);
	    }
	}
	uniq_list(sbl);
	sort_list(sbl);
	
	/*
	 * Now forward this file to the qualified downlinks.
	 */
	for (tmpq = qal; tmpq; tmpq = tmpq->next) {
	    if (tmpq->send) {
		ForwardFile(tmpq->aka, *sbl);
		tic_out++;
	    }
	}
    }

    Magic_ExecCommand();
    Magic_CopyFile();
    Magic_UnpackFile();
    Magic_AdoptFile();

    
    snprintf(Temp, PATH_MAX, "%s/%s", TIC.Inbound, TIC.TicName);
    if (unlink(Temp)) {
	WriteError("$Can't delete %s", Temp);
    }

    free(Temp);
    tidy_qualify(&qal);
    return 0;
}
Ejemplo n.º 30
0
int msgq::tmpscan()
{
	int	found=0;

	time(&current_time);

	DIR *tmpdir=opendir(TMPDIR);

	if (!tmpdir)	clog_msg_errno();

	struct dirent *de;
	std::string	subdir;
	std::string	ctlfile, datfile, newctlfile, newdatfile;
	struct	stat stat_buf;
	std::string	qdir, qname;

	while ((de=readdir(tmpdir)) != 0)
	{
	const char *p;

		for (p=de->d_name; *p; p++)
			if (!isdigit((int)(unsigned char)*p))	break;
		if (*p)	continue;	// Subdirs must be named all digits

		subdir=TMPDIR "/";
		subdir += de->d_name;

		DIR *subde=opendir(subdir.c_str());

		while ((de=readdir(subde)) != 0 && found < 100)
		{
			if (strcmp(de->d_name, ".") == 0 ||
				strcmp(de->d_name, "..") == 0)	continue;

			ctlfile=subdir;
			ctlfile += '/';
			ctlfile += de->d_name;

			int	i=-1;

			if (stat(ctlfile.c_str(), &stat_buf))	continue;

			size_t j=ctlfile.size();

			while (j)
			{
				if (ctlfile[--j] == '/')
					break;

				if (ctlfile[j] == '.')
				{
					i=j;
					break;
				}
			}

		ino_t	inum=stat_buf.st_ino;

		// Cleanup timeout. Should always be sufficiently longer than
		// the submit timeout set in submit.C via alarm_timeout.

			if (stat_buf.st_mtime < current_time - 48 * 60 * 60)
			{
				if (de->d_name[0] == 'D')
				{
					datfile=subdir + "/C" +
						(de->d_name+1);

					if (stat(datfile.c_str(), &stat_buf)
					    == 0)
						continue;
						// Wait until the C file is
						// purged

				// Be carefull with Cnnnn.x files, because
				// Cnnnn.1 is used to hold submission of all
				// of them.  A race condition can leave
				// Cnnnn.1 in a submittable state, so if it
				// is removed, other copies of this message
				// can become submittable, during a very small
				// window.

				} else if (de->d_name[0] == 'C' && i >= 0)
				{

				// This race condition is handled simply
				// by not removing Cxxxxx.n if Cxxxxx.n+1
				// exists.

					char	nbuf[NUMBUFSIZE];

					datfile=ctlfile.substr(0, i);

					size_t	n=atoi( ctlfile.c_str()+i+1);

					++n;

					datfile += '.';
					datfile += libmail_str_size_t(n, nbuf);

					if (stat(datfile.c_str(), &stat_buf)
					    == 0)
						continue;
						// Wait until the C.1 file is
						// purged

					unlink(ctlfile.c_str());

					ctlfile=subdir + "/D" +
						(de->d_name+1);
					/* FALLTHRU */
				}
				unlink(ctlfile.c_str());
				continue;
			}

			if (de->d_name[0] != 'C')	continue;
			if (i >= 0)
			{
				datfile=ctlfile.substr(0, i);
				datfile += ".1";

				if (ctlfile == datfile ||
				    stat(datfile.c_str(), &stat_buf) == 0)
					continue;
			}


			datfile=subdir + "/D" + (de->d_name+1);

			newdatfile=qmsgsdatname(inum);
			newctlfile=qmsgsctlname(inum);

			struct	ctlfile ctf;

			if ((access(datfile.c_str(), 0) == 0 &&
			     access(newdatfile.c_str(), 0) == 0) ||
			    access(newctlfile.c_str(), 0) == 0 ||
			    ctlfile_openfn(ctlfile.c_str(), &ctf, 0, 0))
			{
				clog_msg_start_err();
				clog_msg_str("QUEUE FILE CORRUPTION: inode ");
				clog_msg_uint(inum);
				clog_msg_send();
				utime(ctlfile.c_str(), 0);
				// Keep it around
				continue;
			}

		time_t	nextattempt=current_time+delaytime;

			if ((i=ctlfile_searchfirst(&ctf,
				COMCTLFILE_SUBMITDELAY)) >= 0)
				nextattempt=current_time+
					atoi(ctf.lines[i]+1);

			qname=qmsgqname(inum, nextattempt);

			ctlfile_nextattempt(&ctf, nextattempt);

			if (link(ctlfile.c_str(), qname.c_str()))
			{
				mkdir(qmsgqdir(current_time),0755);
				if (link(ctlfile.c_str(), qname.c_str())
				    && errno != EEXIST)
					clog_msg_errno();
			}

			if (rename(datfile.c_str(), newdatfile.c_str()))
			{
				mkdir(qmsgsdir(inum), 0755);
					// We may need to create this dir
				rename(datfile.c_str(), newdatfile.c_str());
			}

			if (rename(ctlfile.c_str(), newctlfile.c_str()))
				clog_msg_errno();

			for (i=qname.size(); i; )
			{
				if (qname[--i] == '/')
					break;
			}

			qdir=qname.substr(0, i);
			qname=qname.substr(i+1);
			++found;
			ctlfile_close(&ctf);

			queuescan3(qdir, qname, de->d_name);
		}
		closedir(subde);

		if (stat(subdir.c_str(), &stat_buf) == 0 &&
			stat_buf.st_mtime < current_time - 2 * 60 * 60)
			rmdir(subdir.c_str());	// Just give it a try
	}
	closedir(tmpdir);
	return (found);
}