2010-11-06 23:41:49 -07:00
|
|
|
/* Any copyright is dedicated to the Public Domain.
|
|
|
|
* http://creativecommons.org/publicdomain/zero/1.0/
|
|
|
|
*/
|
|
|
|
|
|
|
|
#ifdef XP_WIN
|
|
|
|
# include <windows.h>
|
|
|
|
# include <direct.h>
|
|
|
|
# include <io.h>
|
|
|
|
typedef WCHAR NS_tchar;
|
|
|
|
# define NS_main wmain
|
2011-04-11 21:23:36 -07:00
|
|
|
# define F_OK 00
|
|
|
|
# define W_OK 02
|
|
|
|
# define R_OK 04
|
|
|
|
# define stat _stat
|
2010-11-06 23:41:49 -07:00
|
|
|
# define NS_T(str) L ## str
|
|
|
|
# define NS_tsnprintf(dest, count, fmt, ...) \
|
2011-04-11 21:23:36 -07:00
|
|
|
{ \
|
2010-11-06 23:41:49 -07:00
|
|
|
int _count = count - 1; \
|
|
|
|
_snwprintf(dest, _count, fmt, ##__VA_ARGS__); \
|
2011-04-11 21:23:36 -07:00
|
|
|
dest[_count] = L'\0'; \
|
|
|
|
}
|
|
|
|
# define NS_taccess _waccess
|
|
|
|
# define NS_tchdir _wchdir
|
2010-11-06 23:41:49 -07:00
|
|
|
# define NS_tfopen _wfopen
|
2010-11-18 17:20:58 -08:00
|
|
|
# define NS_tstrcmp wcscmp
|
|
|
|
# define NS_ttoi _wtoi
|
2011-04-11 21:23:36 -07:00
|
|
|
# define NS_tstat _wstat
|
2010-11-06 23:41:49 -07:00
|
|
|
# define LOG_S "%S"
|
|
|
|
#else
|
|
|
|
# include <unistd.h>
|
|
|
|
# define NS_main main
|
|
|
|
typedef char NS_tchar;
|
|
|
|
# define NS_T(str) str
|
|
|
|
# define NS_tsnprintf snprintf
|
2011-04-11 21:23:36 -07:00
|
|
|
# define NS_taccess access
|
|
|
|
# define NS_tchdir chdir
|
2010-11-06 23:41:49 -07:00
|
|
|
# define NS_tfopen fopen
|
2010-11-18 17:20:58 -08:00
|
|
|
# define NS_tstrcmp strcmp
|
|
|
|
# define NS_ttoi atoi
|
2011-04-11 21:23:36 -07:00
|
|
|
# define NS_tstat stat
|
2010-11-06 23:41:49 -07:00
|
|
|
# define LOG_S "%s"
|
|
|
|
#endif
|
|
|
|
|
2010-11-18 17:20:58 -08:00
|
|
|
#include <stdlib.h>
|
2010-11-06 23:41:49 -07:00
|
|
|
#include <stdio.h>
|
2010-11-18 17:20:58 -08:00
|
|
|
#include <string.h>
|
2011-04-11 21:23:36 -07:00
|
|
|
#include <sys/types.h>
|
|
|
|
#include <sys/stat.h>
|
2010-11-06 23:41:49 -07:00
|
|
|
|
|
|
|
#ifndef MAXPATHLEN
|
|
|
|
# ifdef PATH_MAX
|
|
|
|
# define MAXPATHLEN PATH_MAX
|
|
|
|
# elif defined(MAX_PATH)
|
|
|
|
# define MAXPATHLEN MAX_PATH
|
|
|
|
# elif defined(_MAX_PATH)
|
|
|
|
# define MAXPATHLEN _MAX_PATH
|
|
|
|
# elif defined(CCHMAXPATH)
|
|
|
|
# define MAXPATHLEN CCHMAXPATH
|
|
|
|
# else
|
|
|
|
# define MAXPATHLEN 1024
|
|
|
|
# endif
|
|
|
|
#endif
|
|
|
|
|
2011-04-11 21:23:36 -07:00
|
|
|
static void
|
|
|
|
WriteMsg(const NS_tchar *path, const char *status)
|
|
|
|
{
|
|
|
|
FILE* outFP = NS_tfopen(path, NS_T("wb"));
|
|
|
|
if (!outFP)
|
|
|
|
return;
|
|
|
|
|
|
|
|
fprintf(outFP, "%s\n", status);
|
|
|
|
fclose(outFP);
|
|
|
|
outFP = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
static bool
|
|
|
|
CheckMsg(const NS_tchar *path, const char *expected)
|
|
|
|
{
|
|
|
|
if (NS_taccess(path, F_OK)) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
FILE *inFP = NS_tfopen(path, NS_T("rb"));
|
|
|
|
if (!inFP) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
struct stat ms;
|
|
|
|
if (fstat(fileno(inFP), &ms)) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
char *mbuf = (char *) malloc(ms.st_size + 1);
|
|
|
|
if (!mbuf) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
size_t r = ms.st_size;
|
|
|
|
char *rb = mbuf;
|
|
|
|
size_t c = fread(rb, sizeof(char), 50, inFP);
|
|
|
|
r -= c;
|
|
|
|
rb += c;
|
|
|
|
if (c == 0 && r) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
mbuf[ms.st_size] = '\0';
|
|
|
|
rb = mbuf;
|
|
|
|
|
|
|
|
fclose(inFP);
|
|
|
|
inFP = NULL;
|
|
|
|
return strcmp(rb, expected) == 0;
|
|
|
|
}
|
|
|
|
|
2010-11-06 23:41:49 -07:00
|
|
|
int NS_main(int argc, NS_tchar **argv)
|
|
|
|
{
|
|
|
|
|
2011-04-11 21:23:36 -07:00
|
|
|
if (argc < 3) {
|
2010-11-18 17:20:58 -08:00
|
|
|
fprintf(stderr, \
|
|
|
|
"\n" \
|
|
|
|
"Application Update Service Test Helper\n" \
|
|
|
|
"\n" \
|
2011-04-11 21:23:36 -07:00
|
|
|
"Usage: WORKINGDIR INFILE OUTFILE -s SECONDS [FILETOLOCK]\n" \
|
|
|
|
" or: WORKINGDIR LOGFILE [ARG2 ARG3...]\n" \
|
2010-11-18 17:20:58 -08:00
|
|
|
"\n" \
|
2011-04-11 21:23:36 -07:00
|
|
|
" WORKINGDIR \tThe relative path to the working directory to use.\n" \
|
|
|
|
" INFILE \tThe relative path from the working directory for the file to\n" \
|
|
|
|
" \tread actions to perform such as finish.\n" \
|
|
|
|
" OUTFILE \tThe relative path from the working directory for the file to\n" \
|
|
|
|
" \twrite status information.\n" \
|
2010-11-18 17:20:58 -08:00
|
|
|
" SECONDS \tThe number of seconds to sleep.\n" \
|
2011-04-11 21:23:36 -07:00
|
|
|
" FILETOLOCK \tThe relative path from the working directory to an existing\n" \
|
|
|
|
" \tfile to open exlusively.\n" \
|
|
|
|
" \tOnly available on Windows platforms and silently ignored on\n" \
|
2010-11-18 17:20:58 -08:00
|
|
|
" \tother platforms.\n" \
|
2011-04-11 21:23:36 -07:00
|
|
|
" LOGFILE \tThe relative path from the working directory to log the\n" \
|
|
|
|
" \tcommand line arguments.\n" \
|
|
|
|
" ARG2 ARG3...\tArguments to write to the LOGFILE after the preceding command\n" \
|
|
|
|
" \tline arguments.\n" \
|
2010-11-18 17:20:58 -08:00
|
|
|
"\n" \
|
2011-04-11 21:23:36 -07:00
|
|
|
"Note: All paths must be relative.\n" \
|
2010-11-18 17:20:58 -08:00
|
|
|
"\n");
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2011-04-11 21:23:36 -07:00
|
|
|
int i = 0;
|
|
|
|
|
|
|
|
if (NS_tchdir(argv[1]) != 0) {
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2010-11-18 17:20:58 -08:00
|
|
|
// File in use test helper section
|
2011-04-11 21:23:36 -07:00
|
|
|
if (!NS_tstrcmp(argv[4], NS_T("-s"))) {
|
|
|
|
NS_tchar inFilePath[MAXPATHLEN];
|
|
|
|
NS_tsnprintf(inFilePath, sizeof(inFilePath)/sizeof(inFilePath[0]),
|
|
|
|
NS_T("%s"), argv[2]);
|
|
|
|
NS_tchar outFilePath[MAXPATHLEN];
|
|
|
|
NS_tsnprintf(outFilePath, sizeof(outFilePath)/sizeof(outFilePath[0]),
|
|
|
|
NS_T("%s"), argv[3]);
|
|
|
|
|
|
|
|
int seconds = NS_ttoi(argv[5]);
|
2010-11-06 23:41:49 -07:00
|
|
|
#ifdef XP_WIN
|
2010-11-18 17:20:58 -08:00
|
|
|
HANDLE hFile = INVALID_HANDLE_VALUE;
|
2011-04-11 21:23:36 -07:00
|
|
|
if (argc == 7) {
|
|
|
|
hFile = CreateFileW(argv[6],
|
2010-11-18 17:20:58 -08:00
|
|
|
DELETE | GENERIC_WRITE, 0,
|
|
|
|
NULL, OPEN_EXISTING, 0, NULL);
|
|
|
|
if (hFile == INVALID_HANDLE_VALUE) {
|
2011-04-11 21:23:36 -07:00
|
|
|
WriteMsg(outFilePath, "error_locking");
|
2010-11-18 17:20:58 -08:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
}
|
2010-11-06 23:41:49 -07:00
|
|
|
|
2011-04-11 21:23:36 -07:00
|
|
|
WriteMsg(outFilePath, "sleeping");
|
|
|
|
while (!CheckMsg(inFilePath, "finish\n") && i++ <= seconds) {
|
|
|
|
Sleep(1000);
|
|
|
|
}
|
2010-11-18 17:20:58 -08:00
|
|
|
|
2011-04-11 21:23:36 -07:00
|
|
|
if (argc == 7) {
|
2010-11-18 17:20:58 -08:00
|
|
|
CloseHandle(hFile);
|
|
|
|
}
|
2010-11-06 23:41:49 -07:00
|
|
|
#else
|
2011-04-11 21:23:36 -07:00
|
|
|
WriteMsg(outFilePath, "sleeping");
|
|
|
|
while (!CheckMsg(inFilePath, "finish\n") && i++ <= seconds) {
|
|
|
|
sleep(1);
|
|
|
|
}
|
2010-11-06 23:41:49 -07:00
|
|
|
#endif
|
2011-04-11 21:23:36 -07:00
|
|
|
WriteMsg(outFilePath, "finished");
|
2010-11-18 17:20:58 -08:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Command line argument test helper section
|
|
|
|
NS_tchar logFilePath[MAXPATHLEN];
|
2011-04-11 21:23:36 -07:00
|
|
|
NS_tsnprintf(logFilePath, sizeof(logFilePath)/sizeof(logFilePath[0]),
|
|
|
|
NS_T("%s"), argv[2]);
|
2010-11-06 23:41:49 -07:00
|
|
|
|
2011-04-11 21:23:36 -07:00
|
|
|
FILE* logFP = NS_tfopen(logFilePath, NS_T("wb"));
|
2010-11-06 23:41:49 -07:00
|
|
|
for (i = 1; i < argc; ++i) {
|
|
|
|
fprintf(logFP, LOG_S "\n", argv[i]);
|
|
|
|
}
|
|
|
|
|
|
|
|
fclose(logFP);
|
|
|
|
logFP = NULL;
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|