Пример #1
0
/* remove duplicate hashes from the fullfile creation list */
static GList *get_deduplicated_fullfile_list(struct manifest *manifest)
{
	GList *list;
	GList *outfiles = NULL;
	struct file *file;
	struct file *prev = NULL;
	struct file *tmp;

	// presort by hash for easy deduplication
	list = manifest->files = g_list_sort(manifest->files, file_sort_hash);

	for (; list; list = g_list_next(list)) {
		tmp = list->data;

		// find first new file
		if (tmp->last_change == manifest->version) {
			prev = tmp;
			outfiles = g_list_prepend(outfiles, tmp);
			break;
		}
	}
	for (; list; list = g_list_next(list)) {
		file = list->data;

		// add any new file having a unique hash
		//FIXME: rename logic will be needed here
		if (file->is_deleted || (file->last_change != manifest->version)) {
			continue;
		}
		if (!hash_compare(prev->hash, file->hash)) {
			outfiles = g_list_prepend(outfiles, file);
			prev = file;
		}
	}

	// don't want sort by hash else hash[0] locks will be very conflicted
	outfiles = g_list_sort(outfiles, file_sort_filename);

	return outfiles;
}
Пример #2
0
/*
 * compare the variable a with the variable b
 * returns
 *   -1      a < b
 *   +1      a > b
 *   0       a = b
 */
int v_compare(var_t *a, var_t *b) {
  var_num_t dt;
  var_int_t di;
  int i, ci;
  var_t *ea, *eb;

  if (a == 0 || b == 0) {
    err_evsyntax();
    return 0;
  }

  if (a->type == V_INT && b->type == V_INT) {
    di = (a->v.i - b->v.i);
    i = di < 0 ? -1 : di > 0 ? 1 : 0;
    return i;
  } else if ((a->type == V_INT || a->type == V_NUM) && (b->type == V_INT || b->type == V_NUM)) {
    var_num_t left = (a->type == V_NUM) ? a->v.n : a->v.i;
    var_num_t right = (b->type == V_NUM) ? b->v.n : b->v.i;
    dt = (left - right);
    i = dt < 0.0 ? -1 : dt > 0.0 ? 1 : 0;
    return i;
  }
  if ((a->type == V_STR) && (b->type == V_STR)) {
    return strcmp(a->v.p.ptr, b->v.p.ptr);
  }
  if ((a->type == V_STR) && (b->type == V_NUM)) {
    if (a->v.p.ptr[0] == '\0' || is_number((char *) a->v.p.ptr)) { // compare 
      // nums
      dt = v_getval(a);
      return (dt < b->v.n) ? -1 : ((dt == b->v.n) ? 0 : 1);}
return    1;
  }
  if ((a->type == V_NUM) && (b->type == V_STR)) {
    if (b->v.p.ptr[0] == '\0' || is_number((char *) b->v.p.ptr)) { // compare 
      // nums
      dt = v_getval(b);
      return (dt < a->v.n) ? 1 : ((dt == a->v.n) ? 0 : -1);}return
-    1;
  }
  if ((a->type == V_STR) && (b->type == V_INT)) {
    if (a->v.p.ptr[0] == '\0' || is_number((char *) a->v.p.ptr)) { // compare 
      // nums
      di = v_igetval(a);
      return (di < b->v.i) ? -1 : ((di == b->v.i) ? 0 : 1);}
return    1;
  }
  if ((a->type == V_INT) && (b->type == V_STR)) {
    if (b->v.p.ptr[0] == '\0' || is_number((char *) b->v.p.ptr)) { // compare 
      // nums
      di = v_igetval(b);
      return (di < a->v.i) ? 1 : ((di == a->v.i) ? 0 : -1);}return
-    1;
  }
  if ((a->type == V_ARRAY) && (b->type == V_ARRAY)) {
    // check size
    if (a->v.a.size != b->v.a.size) {
      if (a->v.a.size < b->v.a.size) {
        return -1;
      }
      return 1;
    }
    // check every element
    for (i = 0; i < a->v.a.size; i++) {
      ea = (var_t *) (a->v.a.ptr + sizeof(var_t) * i);
      eb = (var_t *) (b->v.a.ptr + sizeof(var_t) * i);
      if ((ci = v_compare(ea, eb)) != 0) {
        return ci;
      }
    }

    return 0;                   // equal
  }

  if (a->type == V_UDS && b->type == V_UDS) {
    return uds_compare(a, b);
  }

  if (a->type == V_HASH && b->type == V_HASH) {
    return hash_compare(a, b);
  }

  err_evtype();                 // ndc 01/08/2001
  return 1;
}
Пример #3
0
int match_manifests(struct manifest *m1, struct manifest *m2)
{
	GList *list1, *list2;
	struct file *file1, *file2;
	int must_sort = 0;
	int count = 0;
	int first = 1;

	if (!m1) {
		printf("Matching manifests up failed: No old manifest!\n");
		return -1;
	}

	if (!m2) {
		printf("Matching manifests up failed: No new manifest!\n");
		return -1;
	}

	m1->files = g_list_sort(m1->files, file_sort_filename);
	m2->files = g_list_sort(m2->files, file_sort_filename);

	list1 = g_list_first(m1->files);
	list2 = g_list_first(m2->files);

	while (list1 && list2) {
		int ret;
		file1 = list1->data;
		file2 = list2->data;

		file1->peer = NULL;
		file2->peer = NULL;

		ret = strcmp(file1->filename, file2->filename);
		if (ret == 0) {
			if (file1->is_deleted && file2->is_deleted && file1->is_rename) {
				file2->is_rename = file1->is_rename;
				hash_assign(file1->hash, file2->hash);
			}

			if (hash_compare(file1->hash, file2->hash) &&
			    file1->is_dir == file2->is_dir &&
			    file1->is_link == file2->is_link &&
			    file1->is_deleted == file2->is_deleted &&
			    file1->is_file == file2->is_file &&
			    file1->is_config == file2->is_config &&
			    file1->is_state == file2->is_state &&
			    file1->is_boot == file2->is_boot &&
			    file1->last_change >= minversion) {
				file2->last_change = file1->last_change;
				file2->is_rename = file1->is_rename;
			} else {
				account_changed_file();
				if (first) {
					LOG(file1, "file changed", "");
					first = 0;
				}
				count++;
			}

			if (!file1->is_deleted || file2->is_deleted) {
				file1->peer = file2;
				file2->peer = file1;
			}

			list1 = g_list_next(list1);
			list2 = g_list_next(list2);
			continue;
		}
		if (first) {
			LOG(file1, "file added? ", "(file2 is %s)", file2->filename);
			first = 0;
		}
		if (ret < 0) {
			struct file *file3;
			/*
			 * if we get here, file1 got deleted... what we must do
			 * is add a file entry for it in the target list.
			 * However, since we're currently walking the list we
			 * HAVE to prepend the entry.. and mark for sort at the
			 * end.
			 */
			file3 = calloc(1, sizeof(struct file));
			if (file3 == NULL) {
				assert(0);
			}

			file3->filename = strdup(file1->filename);
			hash_set_zeros(file3->hash);
			file3->is_deleted = 1;
			file3->is_config = file1->is_config;
			file3->is_state = file1->is_state;
			file3->is_boot = file1->is_boot;

			if (!file1->is_deleted) {
				file3->last_change = m2->version;
			} else {
				file3->last_change = file1->last_change;
				file3->is_rename = file1->is_rename;
				hash_assign(file1->hash, file3->hash);
			}

			file3->peer = file1;
			file1->peer = file3;

			list1 = g_list_next(list1);
			m2->files = g_list_prepend(m2->files, file3);
			m2->count++;
			if (!file1->is_deleted) {
				account_deleted_file();
				count++;
				if (first) {
					LOG(file1, "file got deleted", "");
					first = 0;
				}
			}
			must_sort = 1;
			continue;
		}
		/* if we get here, ret is > 0, which means this is a new file added */
		/* all we do is advance the pointer */
		account_new_file();
		list2 = g_list_next(list2);
		count++;
	}

	/* now deal with the tail ends */
	while (list1) {
		file1 = list1->data;

		struct file *file3;

		if (first) {
			LOG(file1, "file changed tail", "");
			first = 0;
		}
		count++;
		/*
		 * if we get here, file1 got deleted... what we must do is add
		 * a file entry for it in the target list.  However, since
		 * we're currently walking the list we HAVE to prepend the
		 * entry.. and mark for sort at the end.
		 */
		file3 = calloc(1, sizeof(struct file));
		if (file3 == NULL) {
			assert(0);
		}

		file3->filename = strdup(file1->filename);
		hash_set_zeros(file3->hash);
		file3->is_deleted = 1;
		file3->is_config = file1->is_config;
		file3->is_state = file1->is_state;
		file3->is_boot = file1->is_boot;

		if (!file1->is_deleted) {
			file3->last_change = m2->version;
		} else {
			file3->last_change = file1->last_change;
			file3->is_rename = file1->is_rename;
			hash_assign(file1->hash, file3->hash);
		}

		file3->peer = file1;
		file1->peer = file3;

		list1 = g_list_next(list1);
		m2->files = g_list_prepend(m2->files, file3);
		m2->count++;
		if (!file1->is_deleted) {
			account_deleted_file();
		}
		must_sort = 1;
	}

	while (list2) {
		account_new_file();
		list2 = g_list_next(list2);
		if (first) {
			first = 0;
		}
		count++;
	}
	if (must_sort) {
		m2->files = g_list_sort(m2->files, file_sort_filename);
	}

	return count;
}