1/*
2 * Copyright 2016-2017 Haiku, Inc. All rights reserved.
3 * Distributed under the terms of the MIT license
4 *
5 * Authors:
6 *		Alexander von Gluck IV <kallisti5@unixzen.com>
7 *		Brian Hill <supernova@tycho.email>
8 */
9
10#include "SoftwareUpdaterApp.h"
11
12#include <getopt.h>
13#include <stdlib.h>
14
15#include <Catalog.h>
16
17#undef B_TRANSLATION_CONTEXT
18#define B_TRANSLATION_CONTEXT "SoftwareUpdaterApp"
19
20
21static const char* const kUsage = B_TRANSLATE_COMMENT(
22	"Usage:  SoftwareUpdater <command> [ <option> ]\n"
23	"Updates installed packages.\n"
24	"\n"
25	"Commands:\n"
26	"  update     - Search repositories for updates on all packages.\n"
27	"  check      - Check for available updates but only display a "
28		"notification with results.\n"
29	"  full-sync  - Synchronize the installed packages with the "
30		"repositories.\n"
31	"\n"
32	"Options:\n"
33	"  -h or --help       Print this usage help\n"
34	"  -v or --verbose    Output verbose information\n",
35	"Command line usage help")
36;
37
38static struct option const kLongOptions[] = {
39	{"verbose", no_argument, 0, 'v'},
40	{"help", no_argument, 0, 'h'},
41	{NULL}
42};
43
44
45SoftwareUpdaterApp::SoftwareUpdaterApp()
46	:
47	BApplication(kAppSignature),
48	fWorker(NULL),
49	fFinalQuitFlag(false),
50	fActionRequested(FULLSYNC),
51	fVerbose(false),
52	fArgvsAccepted(true)
53{
54}
55
56
57SoftwareUpdaterApp::~SoftwareUpdaterApp()
58{
59	if (fWorker) {
60		fWorker->Lock();
61		fWorker->Quit();
62	}
63}
64
65
66bool
67SoftwareUpdaterApp::QuitRequested()
68{
69	if (fFinalQuitFlag)
70		return true;
71
72	// Simulate a cancel request from window- this gives the updater a chance
73	// to quit cleanly
74	if (fWindowMessenger.IsValid())
75		fWindowMessenger.SendMessage(kMsgCancel);
76	return true;
77}
78
79
80void
81SoftwareUpdaterApp::ReadyToRun()
82{
83	// Argvs no longer accepted once the process starts
84	fArgvsAccepted = false;
85
86	fWorker = new WorkingLooper(fActionRequested, fVerbose);
87}
88
89
90void
91SoftwareUpdaterApp::ArgvReceived(int32 argc, char **argv)
92{
93	if (!fArgvsAccepted) {
94		fputs(B_TRANSLATE("Argument variables are no longer accepted\n"),
95			stderr);
96		return;
97	}
98
99	int c;
100	while ((c = getopt_long(argc, argv, "hv", kLongOptions, NULL)) != -1) {
101		switch (c) {
102			case 0:
103				break;
104			case 'h':
105				fputs(kUsage, stdout);
106				exit(0);
107				break;
108			case 'v':
109				fVerbose = true;
110				break;
111			default:
112				fputs(kUsage, stderr);
113				exit(1);
114				break;
115		}
116	}
117
118	const char* command = "";
119	int32 argCount = argc - optind;
120	if (argCount == 0)
121		return;
122	else if (argCount > 1) {
123		fputs(kUsage, stderr);
124		exit(1);
125	} else
126		command = argv[optind];
127
128	fActionRequested = USER_SELECTION_NEEDED;
129	if (strcmp("update", command) == 0)
130		fActionRequested = UPDATE;
131	else if (strcmp("check", command) == 0)
132		fActionRequested = UPDATE_CHECK_ONLY;
133	else if (strcmp("full-sync", command) == 0)
134		fActionRequested = FULLSYNC;
135	else {
136		fputs(B_TRANSLATE_COMMENT("Unrecognized argument", "Error message"),
137			stderr);
138		fprintf(stderr, " \"%s\"\n", command);
139		fputs(kUsage, stderr);
140	}
141}
142
143
144void
145SoftwareUpdaterApp::MessageReceived(BMessage* message)
146{
147	switch (message->what) {
148		case kMsgRegister:
149			message->FindMessenger(kKeyMessenger, &fWindowMessenger);
150			break;
151
152		case kMsgFinalQuit:
153			fFinalQuitFlag = true;
154			PostMessage(B_QUIT_REQUESTED);
155			break;
156
157		default:
158			BApplication::MessageReceived(message);
159	}
160}
161
162
163int
164main(int argc, const char* const* argv)
165{
166	SoftwareUpdaterApp app;
167	return app.Run();
168}
169