/** Release a transaction. */ int SYMEXPORT alpm_trans_release(alpm_handle_t *handle) { alpm_trans_t *trans; /* Sanity checks */ CHECK_HANDLE(handle, return -1); trans = handle->trans; ASSERT(trans != NULL, RET_ERR(handle, ALPM_ERR_TRANS_NULL, -1)); ASSERT(trans->state != STATE_IDLE, RET_ERR(handle, ALPM_ERR_TRANS_NULL, -1)); int nolock_flag = trans->flags & ALPM_TRANS_FLAG_NOLOCK; _alpm_trans_free(trans); handle->trans = NULL; /* unlock db */ if(!nolock_flag) { if(_alpm_handle_unlock(handle)) { _alpm_log(handle, ALPM_LOG_WARNING, _("could not remove lock file %s\n"), alpm_option_get_lockfile(handle)); alpm_logaction(handle, "warning: could not remove lock file %s\n", alpm_option_get_lockfile(handle)); } } return 0; }
/** Release the library. * Disconnects from the database, removes handle and lockfile * This should be the last alpm call you make. * After this returns, handle should be considered invalid and cannot be reused * in any way. * @param myhandle the context handle * @return 0 on success, -1 on error */ int SYMEXPORT alpm_release(alpm_handle_t *myhandle) { int ret = 0; alpm_db_t *db; CHECK_HANDLE(myhandle, return -1); /* close local database */ db = myhandle->db_local; if(db) { db->ops->unregister(db); myhandle->db_local = NULL; } if(alpm_unregister_all_syncdbs(myhandle) == -1) { ret = -1; } _alpm_handle_unlock(myhandle); _alpm_handle_free(myhandle); #ifdef HAVE_LIBCURL curl_global_cleanup(); #endif return ret; }
/** Release a transaction. */ int SYMEXPORT alpm_trans_release(alpm_handle_t *handle) { alpm_trans_t *trans; /* Sanity checks */ CHECK_HANDLE(handle, return -1); trans = handle->trans; ASSERT(trans != NULL, RET_ERR(handle, ALPM_ERR_TRANS_NULL, -1)); ASSERT(trans->state != STATE_IDLE, RET_ERR(handle, ALPM_ERR_TRANS_NULL, -1)); int nolock_flag = trans->flags & ALPM_TRANS_FLAG_NOLOCK; _alpm_trans_free(trans); handle->trans = NULL; /* unlock db */ if(!nolock_flag) { _alpm_handle_unlock(handle); } return 0; }
/** Update a package database * * An update of the package database \a db will be attempted. Unless * \a force is true, the update will only be performed if the remote * database was modified since the last update. * * This operation requires a database lock, and will return an applicable error * if the lock could not be obtained. * * Example: * @code * alpm_list_t *syncs = alpm_get_syncdbs(); * for(i = syncs; i; i = alpm_list_next(i)) { * alpm_db_t *db = alpm_list_getdata(i); * result = alpm_db_update(0, db); * * if(result < 0) { * printf("Unable to update database: %s\n", alpm_strerrorlast()); * } else if(result == 1) { * printf("Database already up to date\n"); * } else { * printf("Database updated\n"); * } * } * @endcode * * @ingroup alpm_databases * @note After a successful update, the \link alpm_db_get_pkgcache() * package cache \endlink will be invalidated * @param force if true, then forces the update, otherwise update only in case * the database isn't up to date * @param db pointer to the package database to update * @return 0 on success, -1 on error (pm_errno is set accordingly), 1 if up to * to date */ int SYMEXPORT alpm_db_update(int force, alpm_db_t *db) { char *syncpath; alpm_list_t *i; int ret = -1; mode_t oldmask; alpm_handle_t *handle; alpm_siglevel_t level; /* Sanity checks */ ASSERT(db != NULL, return -1); handle = db->handle; handle->pm_errno = 0; ASSERT(db != handle->db_local, RET_ERR(handle, ALPM_ERR_WRONG_ARGS, -1)); ASSERT(db->servers != NULL, RET_ERR(handle, ALPM_ERR_SERVER_NONE, -1)); syncpath = get_sync_dir(handle); if(!syncpath) { return -1; } /* make sure we have a sane umask */ oldmask = umask(0022); level = alpm_db_get_siglevel(db); /* attempt to grab a lock */ if(_alpm_handle_lock(handle)) { free(syncpath); umask(oldmask); RET_ERR(handle, ALPM_ERR_HANDLE_LOCK, -1); } for(i = db->servers; i; i = i->next) { const char *server = i->data; struct dload_payload payload; size_t len; int sig_ret = 0; memset(&payload, 0, sizeof(struct dload_payload)); /* set hard upper limit of 25MiB */ payload.max_size = 25 * 1024 * 1024; /* print server + filename into a buffer */ len = strlen(server) + strlen(db->treename) + 5; /* TODO fix leak syncpath and umask unset */ MALLOC(payload.fileurl, len, RET_ERR(handle, ALPM_ERR_MEMORY, -1)); snprintf(payload.fileurl, len, "%s/%s.db", server, db->treename); payload.handle = handle; payload.force = force; payload.unlink_on_fail = 1; ret = _alpm_download(&payload, syncpath, NULL); _alpm_dload_payload_reset(&payload); if(ret == 0 && (level & ALPM_SIG_DATABASE)) { /* an existing sig file is no good at this point */ char *sigpath = _alpm_sigpath(handle, _alpm_db_path(db)); if(!sigpath) { ret = -1; break; } unlink(sigpath); free(sigpath); /* if we downloaded a DB, we want the .sig from the same server */ /* print server + filename into a buffer (leave space for .sig) */ len = strlen(server) + strlen(db->treename) + 9; /* TODO fix leak syncpath and umask unset */ MALLOC(payload.fileurl, len, RET_ERR(handle, ALPM_ERR_MEMORY, -1)); snprintf(payload.fileurl, len, "%s/%s.db.sig", server, db->treename); payload.handle = handle; payload.force = 1; payload.errors_ok = (level & ALPM_SIG_DATABASE_OPTIONAL); /* set hard upper limit of 16KiB */ payload.max_size = 16 * 1024; sig_ret = _alpm_download(&payload, syncpath, NULL); /* errors_ok suppresses error messages, but not the return code */ sig_ret = payload.errors_ok ? 0 : sig_ret; _alpm_dload_payload_reset(&payload); } if(ret != -1 && sig_ret != -1) { break; } } if(ret == 1) { /* files match, do nothing */ handle->pm_errno = 0; goto cleanup; } else if(ret == -1) { /* pm_errno was set by the download code */ _alpm_log(handle, ALPM_LOG_DEBUG, "failed to sync db: %s\n", alpm_strerror(handle->pm_errno)); goto cleanup; } /* Cache needs to be rebuilt */ _alpm_db_free_pkgcache(db); /* clear all status flags regarding validity/existence */ db->status &= ~DB_STATUS_VALID; db->status &= ~DB_STATUS_INVALID; db->status &= ~DB_STATUS_EXISTS; db->status &= ~DB_STATUS_MISSING; if(sync_db_validate(db)) { /* pm_errno should be set */ ret = -1; } cleanup: if(_alpm_handle_unlock(handle)) { _alpm_log(handle, ALPM_LOG_WARNING, _("could not remove lock file %s\n"), handle->lockfile); } free(syncpath); umask(oldmask); return ret; }