예제 #1
0
static foreign_t
archive_next_header(term_t archive, term_t name)
{ archive_wrapper *ar;
  int rc;

  if ( !get_archive(archive, &ar) )
    return FALSE;
  if ( ar->status == AR_NEW_ENTRY )
    archive_read_data_skip(ar->archive);
  if ( ar->status == AR_OPENED_ENTRY )
    return PL_permission_error("next_header", "archive", archive);

  while ( (rc=archive_read_next_header(ar->archive, &ar->entry)) == ARCHIVE_OK )
  { if ( PL_unify_wchars(name, PL_ATOM, -1,
			 archive_entry_pathname_w(ar->entry)) )
    { ar->status = AR_NEW_ENTRY;
      return TRUE;
    }
    if ( PL_exception(0) )
      return FALSE;
  }

  if ( rc == ARCHIVE_EOF )
    return FALSE;			/* simply at the end */

  return archive_error(ar);
}
예제 #2
0
static foreign_t
archive_property(term_t archive, term_t prop, term_t value)
{ archive_wrapper *ar;
  atom_t pn;
  const char *s;

  if ( !get_archive(archive, &ar) ||
       !PL_get_atom_ex(prop, &pn) )
    return FALSE;

#ifdef HAVE_ARCHIVE_FILTER_COUNT
  if ( pn == ATOM_filter )
  { int i, fcount = archive_filter_count(ar->archive);
    term_t tail = PL_copy_term_ref(value);
    term_t head = PL_new_term_ref();

    for(i=0; i<fcount; i++)
    { s = archive_filter_name(ar->archive, i);

      if ( !s || strcmp(s, "none") == 0 )
	continue;

      if ( !PL_unify_list(tail, head, tail) ||
	   !PL_unify_atom_chars(head, s) )
	return FALSE;
    }
    return PL_unify_nil(tail);
  }
#endif

  return FALSE;
}
예제 #3
0
static foreign_t
archive_open_entry(term_t archive, term_t stream)
{ archive_wrapper *ar;
  IOSTREAM *s;

  if ( !get_archive(archive, &ar) )
    return FALSE;

  if ( (s=Snew(ar, SIO_INPUT|SIO_RECORDPOS, &ar_entry_functions)) )
  { ar->status = AR_OPENED_ENTRY;
    if ( PL_unify_stream(stream, s) )
    { PL_register_atom(ar->symbol);	/* We may no longer reference the */
      return TRUE;			/* archive itself */
    }
    Sclose(s);
    return FALSE;
  }

  return PL_resource_error("memory");
}
예제 #4
0
static foreign_t
archive_close(term_t archive)
{ archive_wrapper *ar;
  int rc;

  if ( !get_archive(archive, &ar) )
    return FALSE;

  if ( ar->status == AR_OPENED_ENTRY )
  { ar->closed_archive = TRUE;

    return TRUE;
  } else if ( (rc=archive_read_free(ar->archive)) == ARCHIVE_OK )
  { ar->entry = NULL;
    ar->archive = NULL;
    ar->symbol = 0;

    return TRUE;
  }

  return archive_error(ar);
}
예제 #5
0
/* Decide if the dependency identified by item is in a onedir or onfile archive
 * then call the appropriate function.
 */
static int extractDependency(ARCHIVE_STATUS *status_list[], const char *item)
{
    ARCHIVE_STATUS *status = NULL;
    char path[_MAX_PATH + 1];
    char filename[_MAX_PATH + 1];
    char srcpath[_MAX_PATH + 1];
    char archive_path[_MAX_PATH + 1];

    char *dirname = NULL;

    VS("Extracting dependencies\n");
    if (splitName(path, filename, item) == -1)
        return -1;

    dirname = dirName(path);
    if (dirname[0] == 0) {
        free(dirname);
        return -1;
    }

    /* We need to identify three situations: 1) dependecies are in a onedir archive
     * next to the current onefile archive, 2) dependencies are in a onedir/onefile
     * archive next to the current onedir archive, 3) dependencies are in a onefile
     * archive next to the current onefile archive.
     */
    VS("Checking if file exists\n");
    if (checkFile(srcpath, "%s/%s/%s", status_list[SELF]->homepath, dirname, filename) == 0) {
        VS("File %s found, assuming is onedir\n", srcpath);
        if (copyDependencyFromDir(status_list[SELF], srcpath, filename) == -1) {
            FATALERROR("Error coping %s\n", filename);
            free(dirname);
            return -1;
        }
    } else if (checkFile(srcpath, "%s../%s/%s", status_list[SELF]->homepath, dirname, filename) == 0) {
        VS("File %s found, assuming is onedir\n", srcpath);
        if (copyDependencyFromDir(status_list[SELF], srcpath, filename) == -1) {
            FATALERROR("Error coping %s\n", filename);
            free(dirname);
            return -1;
        }
    } else {
        VS("File %s not found, assuming is onefile.\n", srcpath);
        if ((checkFile(archive_path, "%s%s.pkg", status_list[SELF]->homepath, path) != 0) &&
            (checkFile(archive_path, "%s%s.exe", status_list[SELF]->homepath, path) != 0) &&
            (checkFile(archive_path, "%s%s", status_list[SELF]->homepath, path) != 0)) {
            FATALERROR("Archive not found: %s\n", archive_path);
            return -1;
        }

        if ((status = get_archive(status_list, archive_path)) == NULL) {
            FATALERROR("Archive not found: %s\n", archive_path);
            return -1;
        }
        if (extractDependencyFromArchive(status, filename) == -1) {
            FATALERROR("Error extracting %s\n", filename);
            free(status);
            return -1;
        }
    }
    free(dirname);

    return 0;
}
예제 #6
0
/**
 * backend_download_packages_thread:
 */
static gboolean
backend_download_packages_thread (PkBackend *backend)
{
	gchar **package_ids;
	string directory;

	package_ids = pk_backend_get_strv(backend, "package_ids");
	directory = _config->FindDir("Dir::Cache::archives") + "partial/";
	pk_backend_set_allow_cancel (backend, true);

	aptcc *m_apt = new aptcc(backend, _cancel);
	pk_backend_set_pointer(backend, "aptcc_obj", m_apt);
	if (m_apt->init()) {
		egg_debug ("Failed to create apt cache");
		delete m_apt;
		pk_backend_finished (backend);
		return false;
	}

	pk_backend_set_status (backend, PK_STATUS_ENUM_QUERY);
	// Create the progress
	AcqPackageKitStatus Stat(m_apt, backend, _cancel);

	// get a fetcher
	pkgAcquire fetcher(&Stat);
	string filelist;
	gchar *pi;

	// TODO this might be useful when the item is in the cache
// 	for (pkgAcquire::ItemIterator I = fetcher.ItemsBegin(); I < fetcher.ItemsEnd();)
// 	{
// 		if ((*I)->Local == true)
// 		{
// 			I++;
// 			continue;
// 		}
//
// 		// Close the item and check if it was found in cache
// 		(*I)->Finished();
// 		if ((*I)->Complete == false) {
// 			Transient = true;
// 		}
//
// 		// Clear it out of the fetch list
// 		delete *I;
// 		I = fetcher.ItemsBegin();
// 	}

	for (uint i = 0; i < g_strv_length(package_ids); i++) {
		pi = package_ids[i];
		if (pk_package_id_check(pi) == false) {
			pk_backend_error_code (backend,
					       PK_ERROR_ENUM_PACKAGE_ID_INVALID,
					       pi);
			delete m_apt;
			pk_backend_finished (backend);
			return false;
		}

		if (_cancel) {
			break;
		}

		pair<pkgCache::PkgIterator, pkgCache::VerIterator> pkg_ver;
		pkg_ver = m_apt->find_package_id(pi);
		// Ignore packages that could not be found or that exist only due to dependencies.
		if (pkg_ver.second.end() == true)
		{
			_error->Error("Can't find this package id \"%s\".", pi);
			continue;
		} else {
			if(!pkg_ver.second.Downloadable()) {
				_error->Error("No downloadable files for %s,"
					      "perhaps it is a local or obsolete" "package?",
					      pi);
				continue;
			}

			string storeFileName;
			if (get_archive(&fetcher,
					m_apt->packageSourceList,
					m_apt->packageRecords,
					pkg_ver.second,
					directory,
					storeFileName))
			{
				Stat.addPackagePair(pkg_ver);
			}
			string destFile = directory + "/" + flNotDir(storeFileName);
			if (filelist.empty()) {
				filelist = destFile;
			} else {
				filelist.append(";" + destFile);
			}
		}
	}

	if (fetcher.Run() != pkgAcquire::Continue
	    && _cancel == false)
	// We failed and we did not cancel
	{
		show_errors(backend, PK_ERROR_ENUM_PACKAGE_DOWNLOAD_FAILED);
		delete m_apt;
		pk_backend_finished (backend);
		return _cancel;
	}

	// send the filelist
	pk_backend_files(backend, NULL, filelist.c_str());

	delete m_apt;
	pk_backend_finished (backend);
	return true;
}
예제 #7
0
static foreign_t
archive_header_prop(term_t archive, term_t field)
{ archive_wrapper *ar;
  functor_t prop;

  if ( !get_archive(archive, &ar) )
    return FALSE;

  if ( !PL_get_functor(field, &prop) )
    return PL_type_error("compound", field);
  if ( ar->status != AR_NEW_ENTRY )
    return PL_permission_error("access", "archive_entry", archive);

  if ( prop == FUNCTOR_filetype1 )
  { __LA_MODE_T type = archive_entry_filetype(ar->entry);
    atom_t name;
    term_t arg = PL_new_term_ref();
    _PL_get_arg(1, field, arg);

    switch(type&AE_IFMT)
    { case AE_IFREG:  name = ATOM_file;             break;
      case AE_IFLNK:  name = ATOM_link;             break;
      case AE_IFSOCK: name = ATOM_socket;           break;
      case AE_IFCHR:  name = ATOM_character_device; break;
      case AE_IFBLK:  name = ATOM_block_device;     break;
      case AE_IFDIR:  name = ATOM_directory;        break;
      case AE_IFIFO:  name = ATOM_fifo;             break;
      default:
	return PL_unify_integer(arg, (type&AE_IFMT));
    }
    return PL_unify_atom(arg, name);
  } else if ( prop == FUNCTOR_mtime1 )
  { time_t stamp = archive_entry_mtime(ar->entry);
    term_t arg = PL_new_term_ref();
    _PL_get_arg(1, field, arg);

    return PL_unify_float(arg, (double)stamp);
  } else if ( prop == FUNCTOR_size1 )
  { int64_t size = archive_entry_size(ar->entry);
    term_t arg = PL_new_term_ref();
    _PL_get_arg(1, field, arg);

    return PL_unify_int64(arg, size);
  } else if ( prop == FUNCTOR_link_target1 )
  { __LA_MODE_T type = archive_entry_filetype(ar->entry);
    const wchar_t *target = NULL;

    switch(type&AE_IFMT)
    { case AE_IFLNK:
	target = archive_entry_symlink_w(ar->entry);
        break;
    }

    if ( target )
    { term_t arg = PL_new_term_ref();
      _PL_get_arg(1, field, arg);

      return PL_unify_wchars(arg, PL_ATOM, (size_t)-1, target);
    }

    return FALSE;
  } else if ( prop == FUNCTOR_format1 )
  { const char *s = archive_format_name(ar->archive);

    if ( s )
    { char lwr[50];
      char *o;
      term_t arg = PL_new_term_ref();
      _PL_get_arg(1, field, arg);

      for(o=lwr; *s && o < lwr+sizeof(lwr); )
	*o++ = tolower(*s++);

      *o = '\0';

      return PL_unify_atom_chars(arg, lwr);
    }
  }

  return PL_domain_error("archive_header_property", field);
}