/*
* Copyright (c) 2007-2022 Hypertriton, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
* USE OF THIS SOFTWARE EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/*
* Install a newly compiled Agar library on the Windows platform.
*/
#include
#include
#include
#define DEFAULT_DIR "C:\\Program Files\\Agar"
char *dstArch = "x86";
const char *miscFiles[] = {
"CHANGELOG.txt",
"INSTALL.txt",
"LICENSE.txt",
"OFL.txt",
"README.txt",
"Logo.png",
"VisualC.html"
};
const int nMiscFiles = sizeof(miscFiles)/sizeof(miscFiles[0]);
int
InstallLibs(const char *dir)
{
char dest[1024];
char *c, *dstFile;
WIN32_FIND_DATA fdata;
DWORD rv;
HANDLE h;
if ((h = FindFirstFile(".\\*", &fdata)) == INVALID_HANDLE_VALUE) {
printf("Invalid file handle (%d)\n", GetLastError());
return (-1);
}
while (FindNextFile(h, &fdata) != 0) {
if ((dstFile = _strdup(fdata.cFileName)) == NULL) {
printf("Out of memory\n");
return (-1);
}
if ((c = strrchr(dstFile, '_')) != NULL &&
strcmp(c, "_static.lib") == 0) {
c[0] = '.'; c[1] = 'l'; c[2] = 'i'; c[3] = 'b';
c[4] = '\0';
} else if ((c = strrchr(dstFile, '.')) != NULL &&
strcmp(c, ".dll") == 0) {
} else {
free(dstFile);
continue;
}
sprintf_s(dest, sizeof(dest), "%s\\lib\\%s\\%s", dir,
dstArch, dstFile);
printf("%s -> %s\n", fdata.cFileName, dest);
if (CopyFile(fdata.cFileName, dest, 0) == 0) {
printf("%s: CopyFile() failed\n", dest);
return (-1);
}
free(dstFile);
}
rv = GetLastError();
FindClose(h);
if (rv != ERROR_NO_MORE_FILES) {
printf("FindNextFile Error (%lu)\n", rv);
return (-1);
}
return (0);
}
int
InstallIncludes(const char *srcDir, const char *dstDir)
{
char path[1024], dest[1024], filename[1024];
char *c;
WIN32_FIND_DATA fdata;
DWORD attrs, rv;
HANDLE h;
CreateDirectory(dstDir, NULL);
printf("> %s\n", srcDir);
sprintf_s(path, sizeof(path), "%s\\*", srcDir);
if ((h = FindFirstFile(path, &fdata)) == INVALID_HANDLE_VALUE) {
printf("Invalid file handle (%d)\n", GetLastError());
return (-1);
}
while (FindNextFile(h, &fdata) != 0) {
if (fdata.cFileName[0] == '.') {
continue;
}
if (strcmp(srcDir, ".") == 0) {
sprintf_s(path, sizeof(path), "%s", fdata.cFileName);
} else {
sprintf_s(path, sizeof(path), "%s\\%s", srcDir,
fdata.cFileName);
}
if ((attrs = GetFileAttributes(path)) ==
INVALID_FILE_ATTRIBUTES) {
printf("GetFileAttributes(%s) failed\n", path);
continue;
}
if (attrs & FILE_ATTRIBUTE_DIRECTORY) {
sprintf_s(dest, sizeof(dest), "%s\\%s", dstDir,
fdata.cFileName);
if (InstallIncludes(path, dest) == -1) {
return (-1);
}
continue;
}
if ((c = strrchr(path, '.')) == NULL ||
c[1] != 'h' || c[2] != '\0') {
continue;
}
sprintf_s(filename, sizeof(filename), "%s", fdata.cFileName);
if ((c = strrchr(filename, '_')) != NULL &&
strcmp(c, "_pub.h") == 0) {
c[0] = '.'; c[1] = 'h'; c[2] = '\0';
sprintf_s(dest, sizeof(dest), "%s\\..\\%s", dstDir,
filename);
} else {
sprintf_s(dest, sizeof(dest), "%s\\%s", dstDir,
filename);
}
printf("%s\n", dest);
if (CopyFile(path, dest, 0) == 0) {
printf("%s: CopyFile() failed\n", dest);
return (-1);
}
}
rv = GetLastError();
FindClose(h);
if (rv != ERROR_NO_MORE_FILES) {
printf("FindNextFile Error (%lu)\n", rv);
return (-1);
}
return (0);
}
int
RemoveEmptyDirs(const char *dir)
{
char path[1024];
WIN32_FIND_DATA fdata;
DWORD attrs, rv;
HANDLE h;
sprintf_s(path, sizeof(path), "%s\\*", dir);
if ((h = FindFirstFile(path, &fdata)) == INVALID_HANDLE_VALUE) {
printf("Invalid file handle (%d)\n", GetLastError());
return (-1);
}
while (FindNextFile(h, &fdata) != 0) {
if (fdata.cFileName[0] == '.') {
continue;
}
sprintf_s(path, sizeof(path), "%s\\%s", dir, fdata.cFileName);
if ((attrs = GetFileAttributes(path)) ==
INVALID_FILE_ATTRIBUTES) {
printf("GetFileAttributes(%s) failed\n", path);
continue;
}
if (attrs & FILE_ATTRIBUTE_DIRECTORY) {
if (RemoveEmptyDirs(path) == -1)
return (-1);
}
}
rv = GetLastError();
FindClose(h);
if (rv != ERROR_NO_MORE_FILES) {
printf("FindNextFile Error (%lu)\n", rv);
return (-1);
}
RemoveDirectory(dir);
return (0);
}
static char *
Prompt(const char *msg, const char *dflt)
{
char buf[1024];
printf("%s [%s]: ", msg, dflt);
fflush(stdout);
fgets(buf, sizeof(buf), stdin);
if (buf[0] == '\n') {
return _strdup(dflt);
} else {
if (buf[strlen(buf)-1] == '\n') {
buf[strlen(buf)-1] = '\0';
}
return _strdup(buf);
}
}
static void
AnyKey(void)
{
char buf[2];
printf("Press any key to continue...");
fflush(stdout);
fgets(buf, sizeof(buf), stdin);
}
int
main(int argc, char *argv[])
{
char *dir = DEFAULT_DIR, *over;
char libdir[2048], incldir[2048], path[2048];
int i;
DWORD attrs;
printf("Agar SDK Installation\n");
printf("=====================\n");
if (argc > 2) {
dstArch = argv[1];
dir = argv[2];
} else if (argc > 1) {
dir = argv[1];
dstArch = Prompt("Architecture (x86 or x64)", "x86");
} else {
dir = Prompt("Installation directory", DEFAULT_DIR);
dstArch = Prompt("Architecture (x86 or x64)", "x86");
}
if (strcmp(dstArch, "x86") != 0 &&
strcmp(dstArch, "x64") != 0) {
printf("No such architecture \"%s\" (use x86 or x64)\n",
dstArch);
AnyKey();
exit(1);
}
printf("Will install %s binaries into %s\n", dstArch, dir);
if ((attrs = GetFileAttributes(dir)) != INVALID_FILE_ATTRIBUTES) {
if (attrs & FILE_ATTRIBUTE_DIRECTORY) {
over = Prompt("Directory exists. Overwrite?", "no");
if (over[0] != 'y' && over[0] != 'Y') {
printf("Aborting installation.\n");
AnyKey();
exit(1);
}
} else {
printf("Existing file: %s; remove first\n", dir);
AnyKey();
exit(1);
}
}
printf("Installing Agar SDK into %s\n", dir);
CreateDirectory(dir, NULL);
sprintf_s(incldir, sizeof(incldir), "%s\\include", dir);
CreateDirectory(incldir, NULL);
sprintf_s(incldir, sizeof(incldir), "%s\\include\\%s", dir, dstArch);
CreateDirectory(incldir, NULL);
sprintf_s(libdir, sizeof(libdir), "%s\\lib", dir);
CreateDirectory(libdir, NULL);
sprintf_s(libdir, sizeof(libdir), "%s\\lib\\%s", dir, dstArch);
CreateDirectory(libdir, NULL);
if (InstallLibs(dir) == -1) {
printf("Failed to install libraries\n");
exit(1);
}
if (InstallIncludes("include", incldir) == -1) {
printf("Failed to install includes\n");
exit(1);
}
RemoveEmptyDirs(incldir);
for (i = 0; i < nMiscFiles; i++) {
sprintf_s(path, sizeof(path), "%s\\%s", dir, miscFiles[i]);
printf("%s\n", path);
if (CopyFile(miscFiles[i], path, 0) == 0) {
printf("%s: CopyFile() failed; ignoring\n", path);
continue;
}
}
printf("\nAgar SDK was successfully installed under %s\n", dir);
AnyKey();
exit(0);
}