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 <StringList.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 BStringList repositoryNames(20); 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 if (!repositoryNames.Add(repoArgs[i])) 87 DIE(B_NO_MEMORY, "can't allocate repository name"); 88 } 89 } 90 91 status_t result; 92 for (int i = 0; i < repositoryNames.CountStrings(); ++i) { 93 const BString& repoName = repositoryNames.StringAt(i); 94 BRepositoryConfig repoConfig; 95 result = roster.GetRepositoryConfig(repoName, &repoConfig); 96 if (result != B_OK) { 97 BPath path; 98 repoConfig.Entry().GetPath(&path); 99 WARN(result, "skipping repository-config '%s'", path.Path()); 100 continue; 101 } 102 BRefreshRepositoryRequest refreshRequest(context, repoConfig); 103 result = refreshRequest.InitCheck(); 104 if (result != B_OK) 105 DIE(result, "unable to create request for refreshing repository"); 106 result = refreshRequest.CreateInitialJobs(); 107 if (result != B_OK) 108 DIE(result, "unable to create necessary jobs"); 109 110 while (BJob* job = refreshRequest.PopRunnableJob()) { 111 result = job->Run(); 112 delete job; 113 if (result != B_OK) 114 return 1; 115 } 116 } 117 118 return 0; 119 } 120