1 /* 2 * Copyright 2011, Oliver Tappe <zooey@hirschkaefere.de> 3 * Distributed under the terms of the MIT License. 4 */ 5 6 7 #include <getopt.h> 8 #include <stdio.h> 9 #include <stdlib.h> 10 11 #include <Errors.h> 12 #include <SupportDefs.h> 13 14 #include <package/Context.h> 15 #include <package/RefreshRepositoryRequest.h> 16 #include <package/PackageRoster.h> 17 18 #include "DecisionProvider.h" 19 #include "JobStateListener.h" 20 #include "pkgman.h" 21 22 23 using namespace BPackageKit; 24 25 26 // TODO: internationalization! 27 28 29 static const char* kCommandUsage = 30 "Usage: %s refresh [<repo-name> ...]\n" 31 "Refreshes all or just the given repositories.\n" 32 "\n" 33 ; 34 35 36 static void 37 print_command_usage_and_exit(bool error) 38 { 39 fprintf(error ? stderr : stdout, kCommandUsage, kProgramName); 40 exit(error ? 1 : 0); 41 } 42 43 44 int 45 command_refresh(int argc, const char* const* argv) 46 { 47 while (true) { 48 static struct option sLongOptions[] = { 49 { "help", no_argument, 0, 'h' }, 50 { 0, 0, 0, 0 } 51 }; 52 53 opterr = 0; // don't print errors 54 int c = getopt_long(argc, (char**)argv, "hu", sLongOptions, NULL); 55 if (c == -1) 56 break; 57 58 switch (c) { 59 case 'h': 60 print_command_usage_and_exit(false); 61 break; 62 63 default: 64 print_command_usage_and_exit(true); 65 break; 66 } 67 } 68 69 // The remaining arguments are repo names. 70 const char* const* repoArgs = argv + optind; 71 int nameCount = argc - optind; 72 73 DecisionProvider decisionProvider; 74 JobStateListener listener; 75 BContext context(decisionProvider, listener); 76 77 BObjectList<BString> repositoryNames(20, true); 78 79 BPackageRoster roster; 80 if (nameCount == 0) { 81 status_t result = roster.GetRepositoryNames(repositoryNames); 82 if (result != B_OK) 83 DIE(result, "can't collect repository names"); 84 } else { 85 for (int i = 0; i < nameCount; ++i) { 86 BString* repoName = new (std::nothrow) BString(repoArgs[i]); 87 if (repoName == NULL) 88 DIE(B_NO_MEMORY, "can't allocate repository name"); 89 repositoryNames.AddItem(repoName); 90 } 91 } 92 93 status_t result; 94 for (int i = 0; i < repositoryNames.CountItems(); ++i) { 95 const BString& repoName = *(repositoryNames.ItemAt(i)); 96 BRepositoryConfig repoConfig; 97 result = roster.GetRepositoryConfig(repoName, &repoConfig); 98 if (result != B_OK) { 99 BPath path; 100 repoConfig.Entry().GetPath(&path); 101 WARN(result, "skipping repository-config '%s'", path.Path()); 102 continue; 103 } 104 BRefreshRepositoryRequest refreshRequest(context, repoConfig); 105 result = refreshRequest.InitCheck(); 106 if (result != B_OK) 107 DIE(result, "unable to create request for refreshing repository"); 108 result = refreshRequest.CreateInitialJobs(); 109 if (result != B_OK) 110 DIE(result, "unable to create necessary jobs"); 111 112 while (BJob* job = refreshRequest.PopRunnableJob()) { 113 result = job->Run(); 114 delete job; 115 if (result != B_OK) 116 return 1; 117 } 118 } 119 120 return 0; 121 } 122