//
// JAPI hޮވꗗ₢킹API
//			(JmssGetChildJobList֐)TvvO
//  (C)NEC Corporation/NEC Soft, Ltd. 1995,2003
//
//    2003.7.26 Create by NEC Soft, Ltd.
//

#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <mbstring.h>
#include <process.h>
#include "JMSS.H"

//
//  R}hFJLIST
//	@\Fw肵Wuԍ̃Wu̔hWũWuԍꗗ
//        擾܂BԋphWu͎w肵Wu璼ځA
//@@@@NꂽWû݂łB
//	FJLIST [IvV] Wuԍ
//@@EIvV
//		/S:E/R/Q/A/ER/QR/QE/A
//			₢킹WȕԂw肵܂B
//					   E IhWu
//					   R  s̔hWu
//					   Q  s҂(N܂)̔hWu
//					   ER Is̔hWu
//					   QE s҂(N܂)IhWu
//					   QR s҂(N܂)s̔hWu
//					   A@SĂ̏Ԃ̔hWu
//		/?	ȈՃwv\܂B
//
//	 IlF 0 I
//			  1 ُI
//

//////////////////////////////////////////////////////////////
//	萔錾
//////////////////////////////////////////////////////////////

// R}hC̍ő咷
#define	MAX_LINE_LENGTH	1024

//     g[N͗p萔
#define	TOKEN_SEPARETOR1	' '		// g[ÑZp[^P()
#define	TOKEN_SEPARETOR2	'\t'	// g[ÑZp[^Q(^u)
#define	TOKEN1				'\"'	// g[N͂ޕ
// IvV͗p萔
#define	OPTION_PREFIX		'/'		// IvVw蕶
#define	OPTION_SEPARETER	':'		// IvVp[^Ƃ̃Zp[^

// IvV
#define	OPTION_JOBSTATUS	"S"		// ₢킹Wȕ

// Wu
#define	JOBSTATUS_END		"E"		// WuI@(END)
#define	JOBSTATUS_RUN		"R"		// Wus(RUN)
#define	JOBSTATUS_QUE		"Q"		// Wus(QUE)
#define	JOBSTATUS_ENDRUN	"ER"	// sI@@@(END&RUN)
#define	JOBSTATUS_QUERUN	"QR"	// L[҂s(QUE&RUN)
#define	JOBSTATUS_QUEEND	"QE"	// L[҂I@(QUE&END)
#define	JOBSTATUS_ALL		"A"		// SẴWu(ALL)

// ֐̃G[R[h
#define	JLIST_ERROR_BADOPTION	2
#define	JLIST_ERROR_NOJOBNUM		3

// i[łWu̍ő吔
#define JLIST_MAXCHILDNUM		128

//	Wus
char	*StatusInfo_ca[12] =
  {
	"s   ",	/* 0 */
	"I     ",	/* 1 */
	"I ",	/* 2 */
	"Nװ  ",	/* 3 */
	"đ҂",	/* 5 */
	"ꎞ~ ",	/* 4 */
	"đM",	/* 6 */
	"s҂ ",	/* 7 */
	"ۗ     ",	/* 8 */
	"N   ",	/* 9 */
	"s     "		/*10 */
	"̑   "		/*11 */
  };

//	WuD揇
char	*Priority_ca[5] =
  {
	"REALTIME",		//	0:JMSS_PRIORITY_REAL
	"HIGH    ",			//	1:JMSS_PRIORITY_HIGH
	"NORMAL  ",		//	2:JMSS_PRIORITY_NORMAL
	"IDLE    ",			//	3JMSS_PRIORITY_IDLE
	"s    "
  };

//////////////////////////////////////////////////////////////
//	vg^Cv錾
//////////////////////////////////////////////////////////////
//	p[^\
typedef struct _JMSSGETPARAM {
	LONG				lJobNo;			//	Wuԍ
	DWORD				dwJobStatus;	//	Wȕ
} JMSSGETPARAM, FAR *LPJMSSGETPARAM;

DWORD JSetOptionInfo(LPJMSSGETPARAM);
BOOL  PutStdOut(LPSTR);
char* JGetToken(char*, char**);
void  JShortenString(char*, DWORD);
BOOL  JCheckChildJob(VOID);
void  JPrintUsage(void);
void  JPrintJobStatus(LPJMSSJOBINFO);


//////////////////////////////////////////////////////////////
//	
//////////////////////////////////////////////////////////////

//
// C֐
//
//@F int  argc; R}hC̐
//         char argv; R}hC̕ւ
//                    |C^z
//
//@ԂlF 0 I
//           1 ُI
//
int main(
	int		argc,
	char	*argv[])
{
	JMSSGETPARAM		stJmssGetParam;    	// p[^
	JMSSJOBINFO			stJmssJobInfo;		// Wu
	DWORD				dwJobCount = JLIST_MAXCHILDNUM;
											// i[łWu̍ő吔w
	DWORD				dwaChildJobNo[128];	// hWũWuWuԍi[
	DWORD				dwResult;			// ֐l
	UINT				i;
	char				caMessage[256];
	char				caJobNo[32];		// Wuԍ()


	// p[^Ȃ͊ȈՃwv\ďI
	if (argc == 1) {
		JPrintUsage();
		return 1;
	}

	// vWuꗗ̏
	memset(&stJmssGetParam, 0, sizeof(JMSSGETPARAM));

	// IvVWJ
	dwResult = JSetOptionInfo(&stJmssGetParam);
	switch (dwResult) {
		case 0:		// I
			break;
		case JLIST_ERROR_BADOPTION:
			PutStdOut("IvV̎w肪Ⴂ܂B\r\n");
			return 1;
		case JLIST_ERROR_NOJOBNUM:
			PutStdOut("Wuԍw肳Ă܂B\r\n");
			return 1;
	}

	// hWuv
	dwResult = JmssGetChildJobList(
				"",
				stJmssGetParam.lJobNo,
				stJmssGetParam.dwJobStatus,
				&dwJobCount,
				dwaChildJobNo );

	// ֐̕ԋpR[h̔
	switch (dwResult) {
		case 0:		// I
			break;

		case JMSS_PARAM_ERROR:		// p[^s
			wsprintf(caMessage, "p[^słB(G[R[h:%08lx)\r\n", dwResult);
			PutStdOut(caMessage);
			return 1;

		case JMSS_NO_CONNECT:		// T[oڑs
			wsprintf(caMessage, "WuJMSST[oƐڑɎs܂B(G[R[h:%08lx)\r\n", dwResult);
			PutStdOut(caMessage);
			return 1;

		case JMSS_NOGET_SERVERNAME:	// ftHgT[o擾s
			wsprintf(caMessage, "̃}VJMSST[o擾ł܂B(G[R[h:%08lx)\r\n", dwResult);
			PutStdOut(caMessage);
			return 1;

		case JMSS_SECURITY_NO_USE:	// JMSSpȂ
			wsprintf(caMessage, "݂̃[UJMSSp܂B(G[R[h:%08lx)\r\n", dwResult);
			PutStdOut(caMessage);
			return 1;

		case JMSS_SECURITY_NO_STOP:	// ĎłȂWuw
			wsprintf(caMessage, "[ŮĎȂ߁A[UWu͎wł܂B(G[R[h:%08lx)\r\n", dwResult);
			PutStdOut(caMessage);
			return 1;

		case JMSS_NO_JOB:			// w肵Wuԍ̃WuȂ
			wsprintf(caMessage, "w肵Wuԍ̃Wu͂܂B(G[R[h:%08lx)\r\n", dwResult);
			PutStdOut(caMessage);
			return 1;

		case JMSS_NO_CHILDJOB:		// w肵Wu̔hWuȂ
			wsprintf(caMessage, "w肵Wu̔hWu͂܂B(G[R[h:%08lx)\r\n", dwResult);
			PutStdOut(caMessage);
			return 1;

		case JMSS_NOT_ENOUGH_BUF:		// w肵̈̑傫s
			wsprintf(caMessage, "w肵̈̑傫sĂ܂B(G[R[h:%08lx)\r\n", dwResult);
			PutStdOut(caMessage);
			return 1;

		default:					// ُ̑̈
			wsprintf(caMessage, "w肵Wu̔hWu\ł܂B(G[R[h:%08lx)\r\n", dwResult);
			PutStdOut(caMessage);
			return 1;
	}

	// Wu\
	wsprintf(caJobNo, "eޮޔԍF%ld\r\n", stJmssGetParam.lJobNo );
	PutStdOut(caJobNo);

	//	Wu\
	wsprintf(caMessage, "%s %s %s %s %s %s %s %s %s %s %s %s %s %s\r\n",
					"ޮޔԍ ",
					"Ɩ          ",
					"Jn ",
					"I ",
					"     ",
					"I",
					"հޖ  ",
					"ޮ޷       ",
					"ғϼ        ",
					"ϼ        ",
					"D揇",
					"ޮޖ             ",
					"soѱ",
					"ޮȯ " );

	PutStdOut(caMessage);

	for ( i=0; i < dwJobCount; i++ )
	{
		// Wȕ
		memset(&stJmssJobInfo, 0, sizeof(JMSSJOBINFO));
		// Wu̍\̃TCYZbg
		stJmssJobInfo.dwSize = sizeof(JMSSJOBINFO);

		wsprintf ( caJobNo, "%ld\r\n", dwaChildJobNo[i] );
		dwResult = JmssGetJobStatus ( 	"",
										dwaChildJobNo[i],
										&stJmssJobInfo );
		if ( dwResult )
			return 1;
		JPrintJobStatus(&stJmssJobInfo);
	}
	return 0;
}

//
// ȈՃwv\
//
//@F Ȃ
//
//@ԂlF Ȃ
//
void JPrintUsage()
{
	PutStdOut("\r\ngp@FJLIST.EXE [IvV] Wuԍ\r\n\r\n");
	PutStdOut("@IvVFȉ̃IvVw\łB\r\n");
	PutStdOut("@@[/S:Wu] ₢킹Wȕ\r\n");
	PutStdOut("@@@@@@@@@@@@E@IhWu\r\n");
	PutStdOut("@@@@@@@@@@@@R  s̔hWu\r\n");
	PutStdOut("@@@@@@@@@@@@Q@s(N܂)̔hWu\r\n");
	PutStdOut("@@@@@@@@@@@@ER Is̔hWu\r\n");
	PutStdOut("@@@@@@@@@@@@QE s҂(N܂)IhWu\r\n");
	PutStdOut("@@@@@@@@@@@@QR s҂(N܂)s̔hWu\r\n");
	PutStdOut("@@@@@@@@@@@@A@SĂ̏Ԃ̔hWu\r\n");
	PutStdOut("@WuԍF₢킹WũWuԍw肵܂B\r\n");
}

//
// 擾Wu\
//
//@F
//		LPJMSSJOBINFO		Wu\̂ւ̃|C^
//
//@ԂlF Ȃ
//
void JPrintJobStatus(LPJMSSJOBINFO lpJmssJobInfo)
{
	struct tm			*slpTime;
	char				caStartTime[10], caEndTime[10];
	char				caMessage[1024];
	char				caStatusInfo[10];
	char				caPriority[10];
	char				caExitCode[10];
	char				caMaxElapseTime[10];
	char				caParentJntNo[10];

	memset(caStartTime, 0x00, sizeof(caStartTime));
	memset(caEndTime, 0x00, sizeof(caEndTime));
	memset(caStatusInfo, 0x00, sizeof(caStatusInfo));
	memset(caPriority, 0x00, sizeof(caPriority));
	memset(caExitCode, 0x00, sizeof(caExitCode));
	memset(caMaxElapseTime, 0x00, sizeof(caMaxElapseTime));
	memset(caParentJntNo, 0x00, sizeof(caParentJntNo));
	memset(&caMessage, 0x20, 1024);

	switch (lpJmssJobInfo->dwJobStatus) {
		case JMSS_JOBSTATUS_RUN:			// s
		case JMSS_JOBSTATUS_EVENT_REC: 		//	Cxg҂
		case JMSS_JOBSTATUS_PAUSE:          // ꎞ~(L[ꎞ~܂)
		case JMSS_JOBSTATUS_EVENT_SEND:     //	CxgM
			lstrcpy(caStatusInfo, StatusInfo_ca[lpJmssJobInfo->dwJobStatus]);
			lstrcpy(caPriority, Priority_ca[lpJmssJobInfo->dwPriority]);
			// Jn
			slpTime = localtime(&lpJmssJobInfo->tBgn);
			if ( slpTime )
				wsprintf( caStartTime, "%02d:%02d ",slpTime->tm_hour, slpTime->tm_min);
			else
				memcpy(caStartTime, "      ", 6);
			memcpy(caEndTime, "      ", 6);
			memcpy(caExitCode, "        ",8);
			wsprintf(caMaxElapseTime, "%08d", lpJmssJobInfo->dwMaxElapseTime);
			wsprintf(caParentJntNo, "%08d", lpJmssJobInfo->dwParentJntNo);
			break;

		case JMSS_JOBSTATUS_FINISH:			// I
		case JMSS_JOBSTATUS_TERM:           // I
		case JMSS_JOBSTATUS_ERROR:			// NG[
			lstrcpy(caPriority, Priority_ca[lpJmssJobInfo->dwPriority]);
			lstrcpy(caStatusInfo, StatusInfo_ca[lpJmssJobInfo->dwJobStatus]);
			// Jn
			slpTime = localtime(&lpJmssJobInfo->tBgn);
			if ( slpTime )
				wsprintf( caStartTime, "%02d:%02d ",slpTime->tm_hour, slpTime->tm_min);
			else
				memcpy(caStartTime, "      ", 6);

			// I
			slpTime = localtime(&lpJmssJobInfo->tEnd);
			if (slpTime)
				wsprintf( caEndTime, "%02d:%02d ", slpTime->tm_hour, slpTime->tm_min);
			else
				memcpy(caEndTime, "      ", 6);
			wsprintf(caExitCode, "%08x", lpJmssJobInfo->dwExitCode);
			wsprintf(caMaxElapseTime, "%08d", lpJmssJobInfo->dwMaxElapseTime);
			wsprintf(caParentJntNo, "%08d", lpJmssJobInfo->dwParentJntNo);
			break;

		case JMSS_JOBSTATUS_WAITO:          // s҂
		case JMSS_JOBSTATUS_PENDING:        // ۗ
		case JMSS_JOBSTATUS_EXECUTE:        // N
			lstrcpy(caPriority, Priority_ca[lpJmssJobInfo->dwPriority]);
			lstrcpy(caStatusInfo, StatusInfo_ca[lpJmssJobInfo->dwJobStatus]);
			memcpy(caStartTime, "      ", 6);
			memcpy(caEndTime, "      ", 6);
			memcpy(caExitCode, "        ",8);
			wsprintf(caMaxElapseTime, "%08d", lpJmssJobInfo->dwMaxElapseTime);
			wsprintf(caParentJntNo, "%08d", lpJmssJobInfo->dwParentJntNo);
			break;

		case JMSS_JOBSTATUS_UNKNOWN:        // s
			lstrcpy(caPriority, Priority_ca[lpJmssJobInfo->dwPriority]);
			lstrcpy(caStatusInfo, StatusInfo_ca[10]);
			// Jn
			slpTime = localtime(&lpJmssJobInfo->tBgn);
			if ( slpTime )
				wsprintf( caStartTime, "%02d:%02d ",slpTime->tm_hour, slpTime->tm_min);
			else
				memcpy(caStartTime, "      ", 6);

			wsprintf(caMaxElapseTime, "%08d", lpJmssJobInfo->dwMaxElapseTime);
			wsprintf(caParentJntNo, "%08d", lpJmssJobInfo->dwParentJntNo);
			break;

		default:							// ȊO
			lstrcpy(caPriority, Priority_ca[lpJmssJobInfo->dwPriority]);
			lstrcpy(caStatusInfo, StatusInfo_ca[11]);
			memcpy(caStartTime, "      ", 6);
			memcpy(caEndTime, "      ", 6);
			memcpy(caExitCode, "        ",8);
			wsprintf(caMaxElapseTime, "%08d", lpJmssJobInfo->dwMaxElapseTime);
			wsprintf(caParentJntNo, "%08d", lpJmssJobInfo->dwParentJntNo);
			break;
	}

	wsprintf(caMessage, "%010ld %-16s %s%s%s %s %-8s %-15s %-15s %-15s %-8s %-s %-8s %-8s\r\n",
						lpJmssJobInfo->lJobNo,
						lpJmssJobInfo->caJobName,
						caStartTime,
						caEndTime,
						caStatusInfo,
						caExitCode,
						lpJmssJobInfo->caUserName,
						lpJmssJobInfo->caQueueName,
						lpJmssJobInfo->caWsName,
						lpJmssJobInfo->caCompName,
						caPriority,
						lpJmssJobInfo->caJobPath,
						caMaxElapseTime,
						caParentJntNo );

	PutStdOut(caMessage);

	return;
}

//
// R}hC͂AIvVAR}h{p[^
// āAΉ郁oɊi[B
//
//@F
//		LPJMSSGETPARAM	lpJmssGetParam;	Wu
//
//@ԂlF DWORD
//		TRUE  
//		FALSE G[
//
DWORD JSetOptionInfo(LPJMSSGETPARAM lpJmssGetParam)
{
	char	CommandLine[MAX_LINE_LENGTH+1];	// R}hCꎞi[p
	char*	lpcaNewToken;					// Vg[Nւ̃|C^
	char*	lpcaNextToken;					// ̃g[Nւ̃|C^
	char*	lpcaOptionParam;				// IvṼp[^

	// lݒ

	// R}hC擾
	strcpy(CommandLine, GetCommandLine());

	// g[N؂o
	lpcaNewToken = CommandLine;

	// ŏ̃g[N͂̃R}h̃R}hȂ̂ŃpX
	lpcaNewToken = JGetToken(lpcaNewToken, &lpcaNextToken);
	lpcaNewToken = lpcaNextToken;

	// p[^w肳Ă
	if (lpcaNewToken != NULL) {
		// g[N؂oăIvVAR}h{p[^𔻕ʂ
		while ((lpcaNewToken = JGetToken(lpcaNewToken, &lpcaNextToken)) != NULL) {
			// IvVǂ̔
			if (lpcaNewToken[0] == OPTION_PREFIX) {
				// IvVp[^̕
				if ((lpcaOptionParam = _mbschr(&lpcaNewToken[1], OPTION_SEPARETER))	!= NULL) {
					*lpcaOptionParam = '\0';
					++lpcaOptionParam;
				}
				// eIvV̔
				// Wu
				if (stricmp(&lpcaNewToken[1], OPTION_JOBSTATUS) == 0) {
					if (lpcaOptionParam == NULL) {
						return JLIST_ERROR_BADOPTION;
					}
					if (stricmp(lpcaOptionParam, JOBSTATUS_ALL) == 0) {
						lpJmssGetParam->dwJobStatus = JMSS_CONTROL_ALL;
					} else if (stricmp(lpcaOptionParam, JOBSTATUS_END) == 0) {
						lpJmssGetParam->dwJobStatus = JMSS_CONTROL_END;
					} else if (stricmp(lpcaOptionParam, JOBSTATUS_RUN) == 0) {
						lpJmssGetParam->dwJobStatus = JMSS_CONTROL_RUN;
					} else if (stricmp(lpcaOptionParam, JOBSTATUS_QUE) == 0) {
						lpJmssGetParam->dwJobStatus = JMSS_CONTROL_QUE;
					} else if (stricmp(lpcaOptionParam, JOBSTATUS_ENDRUN) == 0) {
						lpJmssGetParam->dwJobStatus = JMSS_CONTROL_ENDRUN;
					} else if (stricmp(lpcaOptionParam, JOBSTATUS_QUEEND) == 0) {
						lpJmssGetParam->dwJobStatus = JMSS_CONTROL_QUEEND;
					} else if (stricmp(lpcaOptionParam, JOBSTATUS_QUERUN) == 0) {
						lpJmssGetParam->dwJobStatus = JMSS_CONTROL_QUERUN;
					} else {
						return JLIST_ERROR_BADOPTION;
					}
				}
			} else {
				// Wuԍ

				// g[NWuԍƂ
				if (strlen(lpcaNewToken) == 0
					|| strlen(lpcaNewToken) > 256) {
					return JLIST_ERROR_NOJOBNUM;
				}
				lpJmssGetParam->lJobNo = atol(lpcaNewToken);
 				return 0;
			}
			// ̃g[N̐擪؂og[N̐擪Ƃ
			lpcaNewToken = lpcaNextToken;
		}
	}

	// Wuԍw肳ĂȂ
	return JLIST_ERROR_NOJOBNUM;
}

//
// g[N؂oÃg[Nւ̃|C^ԂB
//
//@F
//		char*	String;	g[N؂o
//		char**	String;	̃g[Nւ̃|C^
//
//@ԂlF char *
//		NULL		̃g[N͂Ȃ(̍Ō)
//		̑		݂̃g[Nւ̃|C^
//
char* JGetToken(char* String, char** NextString)
{
	char*	pToken;	// g[N̐擪

	if (String == NULL) {
		*NextString = NULL;
		return NULL;
	}

	// ̃g[No܂Ŕ΂
	while (*String != '\0' && (*String == TOKEN_SEPARETOR1 || *String == TOKEN_SEPARETOR2))
		++String;

	// g[N̍ŏ̕'\0'ȂNULLŏI
	if (*String == '\0') {
		return NULL;
	}

	pToken = String;	// g[N̐擪ۑ

	// g[ÑZp[^o܂ŕ΂
	while (*String != '\0' && *String != TOKEN_SEPARETOR1 && *String != TOKEN_SEPARETOR2) {
		if (*String == TOKEN1) {
			JShortenString(String, 1);	// TOKEN1̕A߂
			while (*String != '\0' && *String != TOKEN1) {
				++String;
			}
			if (*String == TOKEN1) {
				JShortenString(String, 1);	// TOKEN1̕A߂
				continue;					// ߂̂ŁACNgKv
			}
		}
		++String;
	}

	switch (*String) {
		case	'\0':
			if (NextString != NULL)
				*NextString = NULL;
			return pToken;
		case	TOKEN_SEPARETOR1:
		case	TOKEN_SEPARETOR2:
			*String = '\0';
			if (NextString != NULL)
				*NextString = String+1;
			return pToken;
	}
	return pToken;
}

//
// w蕶A擪當߂
//
//@F
//		char *	String;	
//		DWORD	count;	߂镶
//
//@ԂlF Ȃ
//
void JShortenString(char* pStr, DWORD Count)
{
	while(*pStr = *(pStr+Count))
		++pStr;
}

//
// Wo͂Ɏw肳ꂽo͂
//
//@F
//		LPSTR	pStr;	
//
//@ԂlF TRUE  I
//           FALSE ُI
//
BOOL PutStdOut(LPSTR pStr)
{
	DWORD	WriteLength;

	if (WriteFile(GetStdHandle(STD_OUTPUT_HANDLE),
					(LPVOID)pStr,
					strlen(pStr),
					&WriteLength,
					NULL) == FALSE)
		return FALSE;

	if (strlen(pStr) != WriteLength)
		return FALSE;

	return TRUE;
}
