/* -M (--maintainer) search. */ int powaur_maint(alpm_list_t *targets) { if (!targets) { pw_printf(PW_LOG_ERROR, "argument needed for -M\n"); return -1; } else if (alpm_list_count(targets) > 1) { pw_printf(PW_LOG_ERROR, "-M only takes 1 argument\n"); return -1; } int ret; size_t listsz; alpm_list_t *i, *results; struct aurpkg_t *pkg; CURL *curl; curl = curl_easy_new(); if (!curl) { return error(PW_ERR_CURL_INIT); } /* Clear pwerrno */ CLEAR_ERRNO(); results = query_aur(curl, targets->data, AUR_QUERY_MSEARCH); if (pwerrno != PW_ERR_OK) { ret = -1; goto cleanup; } else if (!results) { printf("No packages found.\n"); ret = -1; goto cleanup; } /* Sort by alphabetical order */ listsz = alpm_list_count(results); results = alpm_list_msort(results, listsz, aurpkg_name_cmp); if (config->sort_votes) { results = alpm_list_msort(results, listsz, aurpkg_vote_cmp); } for (i = results; i; i = i->next) { pkg = i->data; printf("%saur/%s%s%s %s%s %s(%d)%s\n", color.bmag, color.nocolor, color.bold, pkg->name, color.bgreen, pkg->version, color.byellow, pkg->votes, color.nocolor); printf("%s%s\n", TAB, pkg->desc); } cleanup: alpm_list_free_inner(results, (alpm_list_fn_free) aurpkg_free); alpm_list_free(results); curl_easy_cleanup(curl); return 0; }
void show_results (void) { if (!results) { return; } alpm_list_fn_cmp fn_cmp = NULL; switch (config.sort) { case S_NAME: fn_cmp = (alpm_list_fn_cmp) results_cmp; break; case S_VOTE: fn_cmp = (alpm_list_fn_cmp) results_votes_cmp; break; case S_POP: fn_cmp = (alpm_list_fn_cmp) results_popularity_cmp; break; case S_IDATE: fn_cmp = (alpm_list_fn_cmp) results_installdate_cmp; break; case S_ISIZE: fn_cmp = (alpm_list_fn_cmp) results_isize_cmp; break; case S_REL: fn_cmp = (alpm_list_fn_cmp) results_relevance_cmp; break; } if (fn_cmp) { results = alpm_list_msort (results, alpm_list_count (results), fn_cmp); } const alpm_list_nav fn_nav = config.rsort ? alpm_list_previous : alpm_list_next; const alpm_list_t *i_first = config.rsort ? alpm_list_last (results) : results; for (const alpm_list_t *i = i_first; i; i = fn_nav (i)) { const results_t *r = i->data; if (r && r->type == R_ALPM_PKG) { print_package ("", r->ele, alpm_pkg_get_str); } else if (r && r->type == R_AUR_PKG) { print_package ("", r->ele, aur_get_str); } } alpm_list_free_inner (results, (alpm_list_fn_free) results_free); alpm_list_free (results); results = NULL; }
void display_targets(void) { alpm_list_t *i, *targets = NULL; alpm_db_t *db_local = alpm_get_localdb(config->handle); for(i = alpm_trans_get_add(config->handle); i; i = alpm_list_next(i)) { alpm_pkg_t *pkg = i->data; pm_target_t *targ = calloc(1, sizeof(pm_target_t)); if(!targ) return; targ->install = pkg; targ->remove = alpm_db_get_pkg(db_local, alpm_pkg_get_name(pkg)); if(alpm_list_find(config->explicit_adds, pkg, pkg_cmp)) { targ->is_explicit = 1; } targets = alpm_list_add(targets, targ); } for(i = alpm_trans_get_remove(config->handle); i; i = alpm_list_next(i)) { alpm_pkg_t *pkg = i->data; pm_target_t *targ = calloc(1, sizeof(pm_target_t)); if(!targ) return; targ->remove = pkg; if(alpm_list_find(config->explicit_removes, pkg, pkg_cmp)) { targ->is_explicit = 1; } targets = alpm_list_add(targets, targ); } targets = alpm_list_msort(targets, alpm_list_count(targets), target_cmp); _display_targets(targets, config->verbosepkglists); FREELIST(targets); }
/** * @brief Find the items in list `lhs` that are not present in list `rhs`. * * @param lhs the first list * @param rhs the second list * @param fn the comparison function * * @return a list containing all items in `lhs` not present in `rhs` */ alpm_list_t SYMEXPORT *alpm_list_diff(const alpm_list_t *lhs, const alpm_list_t *rhs, alpm_list_fn_cmp fn) { alpm_list_t *left, *right; alpm_list_t *ret = NULL; left = alpm_list_copy(lhs); left = alpm_list_msort(left, alpm_list_count(left), fn); right = alpm_list_copy(rhs); right = alpm_list_msort(right, alpm_list_count(right), fn); alpm_list_diff_sorted(left, right, fn, &ret, NULL); alpm_list_free(left); alpm_list_free(right); return ret; }
/* Search sync db for packages. Only works for 1 package now. */ static int sync_search(CURL *curl, alpm_list_t *targets) { alpm_list_t *i, *j, *search_results; alpm_db_t *db; alpm_pkg_t *spkg; struct aurpkg_t *pkg; size_t listsz; search_results = query_aur(curl, targets->data, AUR_QUERY_SEARCH); if (search_results == NULL) { printf("Sorry, no results for %s\n", targets->data); return 0; } listsz = alpm_list_count(search_results); /* Sort by alphabetical order first */ search_results = alpm_list_msort(search_results, listsz, aurpkg_name_cmp); /* Sort by votes */ if (config->sort_votes) { search_results = alpm_list_msort(search_results, listsz, aurpkg_vote_cmp); } for (i = search_results; i; i = i->next) { pkg = (struct aurpkg_t *) i->data; printf("%saur/%s%s%s %s%s %s(%d)%s\n", color.bmag, color.nocolor, color.bold, pkg->name, color.bgreen, pkg->version, color.votecol, pkg->votes, color.nocolor); printf(" %s\n", pkg->desc); } alpm_list_free_inner(search_results, (alpm_list_fn_free) aurpkg_free); alpm_list_free(search_results); return 0; }
/** * @brief Sort a list of size `n` using mergesort algorithm. * * @param list the list to sort * @param n the size of the list * @param fn the comparison function for determining order * * @return the resultant list */ alpm_list_t SYMEXPORT *alpm_list_msort(alpm_list_t *list, size_t n, alpm_list_fn_cmp fn) { if(n > 1) { size_t half = n / 2; size_t i = half - 1; alpm_list_t *left = list, *lastleft = list, *right; while(i--) { lastleft = lastleft->next; } right = lastleft->next; /* tidy new lists */ lastleft->next = NULL; right->prev = left->prev; left->prev = lastleft; left = alpm_list_msort(left, half, fn); right = alpm_list_msort(right, n - half, fn); list = alpm_list_mmerge(left, right, fn); } return list; }
void show_results () { alpm_list_t *i_first; alpm_list_t *i; alpm_list_nav fn_nav=NULL;; alpm_list_fn_cmp fn_cmp=NULL; if (results!=NULL) { switch (config.sort) { case S_NAME: fn_cmp = (alpm_list_fn_cmp) results_cmp; break; case S_VOTE: fn_cmp = (alpm_list_fn_cmp) results_votes_cmp; break; case S_IDATE: fn_cmp = (alpm_list_fn_cmp) results_installdate_cmp; break; case S_ISIZE: fn_cmp = (alpm_list_fn_cmp) results_isize_cmp; break; } if (fn_cmp) results = alpm_list_msort (results, alpm_list_count (results), fn_cmp); if (config.rsort) { fn_nav = (alpm_list_nav) alpm_list_previous; i_first = alpm_list_last (results); } else { fn_nav = (alpm_list_nav) alpm_list_next; i_first = results; } for(i = i_first; i; i = fn_nav(i)) { results_t *r = i->data; if (r->type == R_ALPM_PKG) print_package ("", r->ele, alpm_pkg_get_str); else if (r->type == R_AUR_PKG) print_package ("", r->ele, aur_get_str); } alpm_list_free_inner (results, (alpm_list_fn_free) results_free); alpm_list_free (results); results = NULL; } }
/** Display usage/syntax for the specified operation. * @param op the operation code requested * @param myname basename(argv[0]) */ static void usage(int op, const char * const myname) { #define addlist(s) (list = alpm_list_add(list, s)) alpm_list_t *list = NULL, *i; /* prefetch some strings for usage below, which moves a lot of calls * out of gettext. */ char const *const str_opt = _("options"); char const *const str_file = _("file(s)"); char const *const str_pkg = _("package(s)"); char const *const str_usg = _("usage"); char const *const str_opr = _("operation"); /* please limit your strings to 80 characters in width */ if(op == PM_OP_MAIN) { printf("%s: %s <%s> [...]\n", str_usg, myname, str_opr); printf(_("operations:\n")); printf(" %s {-h --help}\n", myname); printf(" %s {-V --version}\n", myname); printf(" %s {-D --database} <%s> <%s>\n", myname, str_opt, str_pkg); printf(" %s {-Q --query} [%s] [%s]\n", myname, str_opt, str_pkg); printf(" %s {-R --remove} [%s] <%s>\n", myname, str_opt, str_pkg); printf(" %s {-S --sync} [%s] [%s]\n", myname, str_opt, str_pkg); printf(" %s {-T --deptest} [%s] [%s]\n", myname, str_opt, str_pkg); printf(" %s {-U --upgrade} [%s] <%s>\n", myname, str_opt, str_file); printf(_("\nuse '%s {-h --help}' with an operation for available options\n"), myname); } else { if(op == PM_OP_REMOVE) { printf("%s: %s {-R --remove} [%s] <%s>\n", str_usg, myname, str_opt, str_pkg); printf("%s:\n", str_opt); addlist(_(" -c, --cascade remove packages and all packages that depend on them\n")); addlist(_(" -n, --nosave remove configuration files\n")); addlist(_(" -s, --recursive remove unnecessary dependencies\n" " (-ss includes explicitly installed dependencies)\n")); addlist(_(" -u, --unneeded remove unneeded packages\n")); } else if(op == PM_OP_UPGRADE) { printf("%s: %s {-U --upgrade} [%s] <%s>\n", str_usg, myname, str_opt, str_file); addlist(_(" --needed do not reinstall up to date packages\n")); printf("%s:\n", str_opt); } else if(op == PM_OP_QUERY) { printf("%s: %s {-Q --query} [%s] [%s]\n", str_usg, myname, str_opt, str_pkg); printf("%s:\n", str_opt); addlist(_(" -c, --changelog view the changelog of a package\n")); addlist(_(" -d, --deps list packages installed as dependencies [filter]\n")); addlist(_(" -e, --explicit list packages explicitly installed [filter]\n")); addlist(_(" -g, --groups view all members of a package group\n")); addlist(_(" -i, --info view package information (-ii for backup files)\n")); addlist(_(" -k, --check check that package files exist (-kk for file properties)\n")); addlist(_(" -l, --list list the files owned by the queried package\n")); addlist(_(" -m, --foreign list installed packages not found in sync db(s) [filter]\n")); addlist(_(" -n, --native list installed packages only found in sync db(s) [filter]\n")); addlist(_(" -o, --owns <file> query the package that owns <file>\n")); addlist(_(" -p, --file <package> query a package file instead of the database\n")); addlist(_(" -q, --quiet show less information for query and search\n")); addlist(_(" -s, --search <regex> search locally-installed packages for matching strings\n")); addlist(_(" -t, --unrequired list packages not (optionally) required by any\n" " package (-tt to ignore optdepends) [filter]\n")); addlist(_(" -u, --upgrades list outdated packages [filter]\n")); } else if(op == PM_OP_SYNC) { printf("%s: %s {-S --sync} [%s] [%s]\n", str_usg, myname, str_opt, str_pkg); printf("%s:\n", str_opt); addlist(_(" -c, --clean remove old packages from cache directory (-cc for all)\n")); addlist(_(" -g, --groups view all members of a package group\n" " (-gg to view all groups and members)\n")); addlist(_(" -i, --info view package information (-ii for extended information)\n")); addlist(_(" -l, --list <repo> view a list of packages in a repo\n")); addlist(_(" -q, --quiet show less information for query and search\n")); addlist(_(" -s, --search <regex> search remote repositories for matching strings\n")); addlist(_(" -u, --sysupgrade upgrade installed packages (-uu enables downgrades)\n")); addlist(_(" -w, --downloadonly download packages but do not install/upgrade anything\n")); addlist(_(" -y, --refresh download fresh package databases from the server\n" " (-yy to force a refresh even if up to date)\n")); addlist(_(" --needed do not reinstall up to date packages\n")); } else if(op == PM_OP_DATABASE) { printf("%s: %s {-D --database} <%s> <%s>\n", str_usg, myname, str_opt, str_pkg); printf("%s:\n", str_opt); addlist(_(" --asdeps mark packages as non-explicitly installed\n")); addlist(_(" --asexplicit mark packages as explicitly installed\n")); addlist(_(" -k, --check test local database for validity (-kk for sync databases)\n")); } else if(op == PM_OP_DEPTEST) { printf("%s: %s {-T --deptest} [%s] [%s]\n", str_usg, myname, str_opt, str_pkg); printf("%s:\n", str_opt); } switch(op) { case PM_OP_SYNC: case PM_OP_UPGRADE: addlist(_(" --force force install, overwrite conflicting files\n")); addlist(_(" --asdeps install packages as non-explicitly installed\n")); addlist(_(" --asexplicit install packages as explicitly installed\n")); addlist(_(" --ignore <pkg> ignore a package upgrade (can be used more than once)\n")); addlist(_(" --ignoregroup <grp>\n" " ignore a group upgrade (can be used more than once)\n")); /* pass through */ case PM_OP_REMOVE: addlist(_(" -d, --nodeps skip dependency version checks (-dd to skip all checks)\n")); addlist(_(" --assume-installed <package=version>\n" " add a virtual package to satisfy dependencies\n")); addlist(_(" --dbonly only modify database entries, not package files\n")); addlist(_(" --noprogressbar do not show a progress bar when downloading files\n")); addlist(_(" --noscriptlet do not execute the install scriptlet if one exists\n")); addlist(_(" -p, --print print the targets instead of performing the operation\n")); addlist(_(" --print-format <string>\n" " specify how the targets should be printed\n")); break; } addlist(_(" -b, --dbpath <path> set an alternate database location\n")); addlist(_(" -r, --root <path> set an alternate installation root\n")); addlist(_(" -v, --verbose be verbose\n")); addlist(_(" --arch <arch> set an alternate architecture\n")); addlist(_(" --cachedir <dir> set an alternate package cache location\n")); addlist(_(" --color <when> colorize the output\n")); addlist(_(" --config <path> set an alternate configuration file\n")); addlist(_(" --debug display debug messages\n")); addlist(_(" --gpgdir <path> set an alternate home directory for GnuPG\n")); addlist(_(" --logfile <path> set an alternate log file\n")); addlist(_(" --noconfirm do not ask for any confirmation\n")); addlist(_(" --confirm always ask for confirmation\n")); } list = alpm_list_msort(list, alpm_list_count(list), options_cmp); for(i = list; i; i = alpm_list_next(i)) { fputs((const char *)i->data, stdout); } alpm_list_free(list); #undef addlist }
static int local_db_populate(alpm_db_t *db) { size_t est_count; int count = 0; struct stat buf; struct dirent *ent = NULL; const char *dbpath; DIR *dbdir; if(db->status & DB_STATUS_INVALID) { RET_ERR(db->handle, ALPM_ERR_DB_INVALID, -1); } /* note: DB_STATUS_MISSING is not fatal for local database */ dbpath = _alpm_db_path(db); if(dbpath == NULL) { /* pm_errno set in _alpm_db_path() */ return -1; } dbdir = opendir(dbpath); if(dbdir == NULL) { if(errno == ENOENT) { /* no database existing yet is not an error */ db->status &= ~DB_STATUS_EXISTS; db->status |= DB_STATUS_MISSING; return 0; } RET_ERR(db->handle, ALPM_ERR_DB_OPEN, -1); } if(fstat(dirfd(dbdir), &buf) != 0) { RET_ERR(db->handle, ALPM_ERR_DB_OPEN, -1); } db->status |= DB_STATUS_EXISTS; db->status &= ~DB_STATUS_MISSING; if(buf.st_nlink >= 2) { est_count = buf.st_nlink; } else { /* Some filesystems don't subscribe to the two-implicit links school of * thought, e.g. BTRFS, HFS+. See * http://kerneltrap.org/mailarchive/linux-btrfs/2010/1/23/6723483/thread */ est_count = 0; while(readdir(dbdir) != NULL) { est_count++; } rewinddir(dbdir); } if(est_count >= 2) { /* subtract the two extra pointers to get # of children */ est_count -= 2; } /* initialize hash at 50% full */ db->pkgcache = _alpm_pkghash_create(est_count * 2); if(db->pkgcache == NULL){ closedir(dbdir); RET_ERR(db->handle, ALPM_ERR_MEMORY, -1); } while((ent = readdir(dbdir)) != NULL) { const char *name = ent->d_name; alpm_pkg_t *pkg; if(strcmp(name, ".") == 0 || strcmp(name, "..") == 0) { continue; } if(!is_dir(dbpath, ent)) { continue; } pkg = _alpm_pkg_new(); if(pkg == NULL) { closedir(dbdir); RET_ERR(db->handle, ALPM_ERR_MEMORY, -1); } /* split the db entry name */ if(_alpm_splitname(name, &(pkg->name), &(pkg->version), &(pkg->name_hash)) != 0) { _alpm_log(db->handle, ALPM_LOG_ERROR, _("invalid name for database entry '%s'\n"), name); _alpm_pkg_free(pkg); continue; } /* duplicated database entries are not allowed */ if(_alpm_pkghash_find(db->pkgcache, pkg->name)) { _alpm_log(db->handle, ALPM_LOG_ERROR, _("duplicated database entry '%s'\n"), pkg->name); _alpm_pkg_free(pkg); continue; } pkg->origin = PKG_FROM_LOCALDB; pkg->origin_data.db = db; pkg->ops = &local_pkg_ops; pkg->handle = db->handle; /* explicitly read with only 'BASE' data, accessors will handle the rest */ if(local_db_read(pkg, INFRQ_BASE) == -1) { _alpm_log(db->handle, ALPM_LOG_ERROR, _("corrupted database entry '%s'\n"), name); _alpm_pkg_free(pkg); continue; } /* add to the collection */ _alpm_log(db->handle, ALPM_LOG_FUNCTION, "adding '%s' to package cache for db '%s'\n", pkg->name, db->treename); db->pkgcache = _alpm_pkghash_add(db->pkgcache, pkg); count++; } closedir(dbdir); if(count > 0) { db->pkgcache->list = alpm_list_msort(db->pkgcache->list, (size_t)count, _alpm_pkg_cmp); } _alpm_log(db->handle, ALPM_LOG_DEBUG, "added %d packages to package cache for db '%s'\n", count, db->treename); return count; }
/** * pacman_list_sort: * @list: A #PacmanList. * @func: A #GCompareFunc function. * * Sorts @list into an order determined by @func. * * Returns: A sorted #PacmanList. Do not use or free @list afterwards. */ PacmanList *pacman_list_sort (PacmanList *list, GCompareFunc func) { return alpm_list_msort (list, pacman_list_length (list), (alpm_list_fn_cmp) func); }
alpm_list_t* alpm_list_sort_data (alpm_list_t *list, alpm_list_fn_cmp fn) { list = alpm_list_msort (list, alpm_list_count (list), fn); return list; }
static int sync_db_populate(alpm_db_t *db) { const char *dbpath; size_t est_count; int count, fd; struct stat buf; struct archive *archive; struct archive_entry *entry; alpm_pkg_t *pkg = NULL; if(db->status & DB_STATUS_INVALID) { RET_ERR(db->handle, ALPM_ERR_DB_INVALID, -1); } if(db->status & DB_STATUS_MISSING) { RET_ERR(db->handle, ALPM_ERR_DB_NOT_FOUND, -1); } dbpath = _alpm_db_path(db); if(!dbpath) { /* pm_errno set in _alpm_db_path() */ return -1; } fd = _alpm_open_archive(db->handle, dbpath, &buf, &archive, ALPM_ERR_DB_OPEN); if(fd < 0) { return -1; } est_count = estimate_package_count(&buf, archive); db->pkgcache = _alpm_pkghash_create(est_count); if(db->pkgcache == NULL) { db->handle->pm_errno = ALPM_ERR_MEMORY; count = -1; goto cleanup; } while(archive_read_next_header(archive, &entry) == ARCHIVE_OK) { mode_t mode = archive_entry_mode(entry); if(S_ISDIR(mode)) { continue; } else { /* we have desc, depends or deltas - parse it */ if(sync_db_read(db, archive, entry, &pkg) != 0) { _alpm_log(db->handle, ALPM_LOG_ERROR, _("could not parse package description file '%s' from db '%s'\n"), archive_entry_pathname(entry), db->treename); continue; } } } count = alpm_list_count(db->pkgcache->list); if(count > 0) { db->pkgcache->list = alpm_list_msort(db->pkgcache->list, (size_t)count, _alpm_pkg_cmp); } _alpm_log(db->handle, ALPM_LOG_DEBUG, "added %d packages to package cache for db '%s'\n", count, db->treename); cleanup: archive_read_finish(archive); if(fd >= 0) { CLOSE(fd); } return count; }
static int sync_db_populate(alpm_db_t *db) { const char *dbpath; size_t est_count; int count = 0; struct stat buf; struct archive *archive; struct archive_entry *entry; alpm_pkg_t *pkg = NULL; if(db->status & DB_STATUS_INVALID) { RET_ERR(db->handle, ALPM_ERR_DB_INVALID, -1); } if(db->status & DB_STATUS_MISSING) { RET_ERR(db->handle, ALPM_ERR_DB_NOT_FOUND, -1); } if((archive = archive_read_new()) == NULL) { RET_ERR(db->handle, ALPM_ERR_LIBARCHIVE, -1); } archive_read_support_compression_all(archive); archive_read_support_format_all(archive); dbpath = _alpm_db_path(db); if(!dbpath) { /* pm_errno set in _alpm_db_path() */ return -1; } _alpm_log(db->handle, ALPM_LOG_DEBUG, "opening database archive %s\n", dbpath); if(archive_read_open_filename(archive, dbpath, ARCHIVE_DEFAULT_BYTES_PER_BLOCK) != ARCHIVE_OK) { _alpm_log(db->handle, ALPM_LOG_ERROR, _("could not open file %s: %s\n"), dbpath, archive_error_string(archive)); archive_read_finish(archive); RET_ERR(db->handle, ALPM_ERR_DB_OPEN, -1); } if(stat(dbpath, &buf) != 0) { RET_ERR(db->handle, ALPM_ERR_DB_OPEN, -1); } est_count = estimate_package_count(&buf, archive); /* initialize hash at 66% full */ db->pkgcache = _alpm_pkghash_create(est_count * 3 / 2); if(db->pkgcache == NULL) { RET_ERR(db->handle, ALPM_ERR_MEMORY, -1); } while(archive_read_next_header(archive, &entry) == ARCHIVE_OK) { mode_t mode = archive_entry_mode(entry); if(S_ISDIR(mode)) { continue; } else { /* we have desc, depends or deltas - parse it */ if(sync_db_read(db, archive, entry, &pkg) != 0) { _alpm_log(db->handle, ALPM_LOG_ERROR, _("could not parse package description file '%s' from db '%s'\n"), archive_entry_pathname(entry), db->treename); continue; } } } count = alpm_list_count(db->pkgcache->list); if(count > 0) { db->pkgcache->list = alpm_list_msort(db->pkgcache->list, (size_t)count, _alpm_pkg_cmp); } archive_read_finish(archive); _alpm_log(db->handle, ALPM_LOG_DEBUG, "added %d packages to package cache for db '%s'\n", count, db->treename); return count; }
static alpm_list_t *mount_point_list(alpm_handle_t *handle) { alpm_list_t *mount_points = NULL, *ptr; alpm_mountpoint_t *mp; #if defined(HAVE_GETMNTENT) && defined(HAVE_MNTENT_H) /* Linux */ struct mntent *mnt; FILE *fp; fp = setmntent(MOUNTED, "r"); if(fp == NULL) { _alpm_log(handle, ALPM_LOG_ERROR, _("could not open file: %s: %s\n"), MOUNTED, strerror(errno)); return NULL; } while((mnt = getmntent(fp))) { CALLOC(mp, 1, sizeof(alpm_mountpoint_t), RET_ERR(handle, ALPM_ERR_MEMORY, NULL)); STRDUP(mp->mount_dir, mnt->mnt_dir, free(mp); RET_ERR(handle, ALPM_ERR_MEMORY, NULL)); mp->mount_dir_len = strlen(mp->mount_dir); mount_points = alpm_list_add(mount_points, mp); } endmntent(fp); #elif defined(HAVE_GETMNTENT) && defined(HAVE_MNTTAB_H) /* Solaris, Illumos */ struct mnttab mnt; FILE *fp; int ret; fp = fopen("/etc/mnttab", "r"); if(fp == NULL) { _alpm_log(handle, ALPM_LOG_ERROR, _("could not open file %s: %s\n"), "/etc/mnttab", strerror(errno)); return NULL; } while((ret = getmntent(fp, &mnt)) == 0) { CALLOC(mp, 1, sizeof(alpm_mountpoint_t), RET_ERR(handle, ALPM_ERR_MEMORY, NULL)); STRDUP(mp->mount_dir, mnt->mnt_mountp, free(mp); RET_ERR(handle, ALPM_ERR_MEMORY, NULL)); mp->mount_dir_len = strlen(mp->mount_dir); mount_points = alpm_list_add(mount_points, mp); } /* -1 == EOF */ if(ret != -1) { _alpm_log(handle, ALPM_LOG_WARNING, _("could not get filesystem information\n")); } fclose(fp); #elif defined(HAVE_GETMNTINFO) /* FreeBSD (statfs), NetBSD (statvfs), OpenBSD (statfs), OS X (statfs) */ int entries; FSSTATSTYPE *fsp; entries = getmntinfo(&fsp, MNT_NOWAIT); if(entries < 0) { _alpm_log(handle, ALPM_LOG_ERROR, _("could not get filesystem information\n")); return NULL; } for(; entries-- > 0; fsp++) { CALLOC(mp, 1, sizeof(alpm_mountpoint_t), RET_ERR(handle, ALPM_ERR_MEMORY, NULL)); STRDUP(mp->mount_dir, fsp->f_mntonname, free(mp); RET_ERR(handle, ALPM_ERR_MEMORY, NULL)); mp->mount_dir_len = strlen(mp->mount_dir); memcpy(&(mp->fsp), fsp, sizeof(FSSTATSTYPE)); #if defined(HAVE_GETMNTINFO_STATVFS) && defined(HAVE_STRUCT_STATVFS_F_FLAG) mp->read_only = fsp->f_flag & ST_RDONLY; #elif defined(HAVE_GETMNTINFO_STATFS) && defined(HAVE_STRUCT_STATFS_F_FLAGS) mp->read_only = fsp->f_flags & MNT_RDONLY; #endif /* we don't support lazy loading on this platform */ mp->fsinfo_loaded = MOUNT_FSINFO_LOADED; mount_points = alpm_list_add(mount_points, mp); } #endif mount_points = alpm_list_msort(mount_points, alpm_list_count(mount_points), mount_point_cmp); for(ptr = mount_points; ptr != NULL; ptr = ptr->next) { mp = ptr->data; _alpm_log(handle, ALPM_LOG_DEBUG, "discovered mountpoint: %s\n", mp->mount_dir); } return mount_points; }