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/AddRepositoryRequest.h> 15 #include <package/Context.h> 16 #include <package/RefreshRepositoryRequest.h> 17 #include <package/PackageRoster.h> 18 19 #include "DecisionProvider.h" 20 #include "JobStateListener.h" 21 #include "pkgman.h" 22 23 24 using namespace BPackageKit; 25 26 27 // TODO: internationalization! 28 29 30 static const char* kCommandUsage = 31 "Usage: %s add-repo <repo-URL> [<repo-URL> ...]\n" 32 "Adds one or more repositories by downloading them from the given URL(s).\n" 33 "\n" 34 ; 35 36 37 static void 38 print_command_usage_and_exit(bool error) 39 { 40 fprintf(error ? stderr : stdout, kCommandUsage, kProgramName); 41 exit(error ? 1 : 0); 42 } 43 44 45 int 46 command_add_repo(int argc, const char* const* argv) 47 { 48 bool asUserRepository = false; 49 50 while (true) { 51 static struct option sLongOptions[] = { 52 { "help", no_argument, 0, 'h' }, 53 { "user", no_argument, 0, 'u' }, 54 { 0, 0, 0, 0 } 55 }; 56 57 opterr = 0; // don't print errors 58 int c = getopt_long(argc, (char**)argv, "hu", sLongOptions, NULL); 59 if (c == -1) 60 break; 61 62 switch (c) { 63 case 'h': 64 print_command_usage_and_exit(false); 65 break; 66 67 case 'u': 68 asUserRepository = true; 69 break; 70 71 default: 72 print_command_usage_and_exit(true); 73 break; 74 } 75 } 76 77 // The remaining arguments are repo URLs, i. e. at least one more argument. 78 if (argc < optind + 1) 79 print_command_usage_and_exit(true); 80 81 const char* const* repoURLs = argv + optind; 82 int urlCount = argc - optind; 83 84 DecisionProvider decisionProvider; 85 JobStateListener listener; 86 BContext context(decisionProvider, listener); 87 88 status_t result; 89 for (int i = 0; i < urlCount; ++i) { 90 AddRepositoryRequest addRequest(context, repoURLs[i], asUserRepository); 91 result = addRequest.InitCheck(); 92 if (result != B_OK) 93 DIE(result, "unable to create request for adding repository"); 94 result = addRequest.CreateInitialJobs(); 95 if (result != B_OK) 96 DIE(result, "unable to create necessary jobs"); 97 98 while (BJob* job = addRequest.PopRunnableJob()) { 99 result = job->Run(); 100 delete job; 101 if (result == B_CANCELED) 102 return 1; 103 } 104 105 // now refresh the repo-cache of the new repository 106 BString repoName = addRequest.RepositoryName(); 107 BPackageRoster roster; 108 BRepositoryConfig repoConfig; 109 roster.GetRepositoryConfig(repoName, &repoConfig); 110 BRefreshRepositoryRequest refreshRequest(context, repoConfig); 111 result = refreshRequest.InitCheck(); 112 if (result != B_OK) 113 DIE(result, "unable to create request for refreshing repository"); 114 result = refreshRequest.CreateInitialJobs(); 115 if (result != B_OK) 116 DIE(result, "unable to create necessary jobs"); 117 118 while (BJob* job = refreshRequest.PopRunnableJob()) { 119 result = job->Run(); 120 delete job; 121 if (result == B_CANCELED) 122 return 1; 123 } 124 } 125 126 return 0; 127 } 128