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/Roster.h> 18 19 #include "MyDecisionProvider.h" 20 #include "MyJobStateListener.h" 21 #include "pkgman.h" 22 23 24 using namespace Haiku::Package; 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 MyDecisionProvider decisionProvider; 85 Context context(decisionProvider); 86 MyJobStateListener listener; 87 context.SetJobStateListener(&listener); 88 89 status_t result; 90 for (int i = 0; i < urlCount; ++i) { 91 AddRepositoryRequest addRequest(context, repoURLs[i], asUserRepository); 92 result = addRequest.CreateInitialJobs(); 93 if (result != B_OK) 94 DIE(result, "unable to create necessary jobs"); 95 96 while (Job* job = addRequest.PopRunnableJob()) { 97 result = job->Run(); 98 delete job; 99 if (result == B_CANCELED) 100 return 1; 101 } 102 103 BString repoName = addRequest.RepositoryName(); 104 Roster roster; 105 RepositoryConfig repoConfig; 106 roster.GetRepositoryConfig(repoName, &repoConfig); 107 RefreshRepositoryRequest refreshRequest(context, repoConfig); 108 result = refreshRequest.CreateInitialJobs(); 109 if (result != B_OK) 110 DIE(result, "unable to create necessary jobs"); 111 112 while (Job* job = refreshRequest.PopRunnableJob()) { 113 result = job->Run(); 114 delete job; 115 if (result == B_CANCELED) 116 return 1; 117 } 118 } 119 120 return 0; 121 } 122