From: Keith Vetter Date: Fri, 28 Apr 1995 18:34:37 +0000 (+0000) Subject: Added windows gssapi demo program X-Git-Tag: krb5-1.0-beta5~139 X-Git-Url: http://git.tremily.us/?a=commitdiff_plain;h=0d6ee29c39b7b40916d609c589f20cf14d50f72c;p=krb5.git Added windows gssapi demo program git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@5613 dc483132-0cff-0310-8789-dd5450dbe970 --- diff --git a/src/windows/changelo b/src/windows/changelo index 8427dc619..56ea910b1 100644 --- a/src/windows/changelo +++ b/src/windows/changelo @@ -1,3 +1,7 @@ +Fri Apr 28 11:21:01 1995 Keith Vetter (keithv@fusion.com) + + * makefile: added gss, new subdirectory for gss demo. + Wed Apr 19 18:37:07 1995 Keith Vetter (keithv@fusion.com) * readme: updated about how to make it, and about gssapi. diff --git a/src/windows/gss/changelo b/src/windows/gss/changelo new file mode 100644 index 000000000..7ee4d057b --- /dev/null +++ b/src/windows/gss/changelo @@ -0,0 +1,5 @@ +Fri Apr 28 11:20:38 1995 Keith Vetter (keithv@fusion.com) + + * Initial release + + diff --git a/src/windows/gss/gss-clie.c b/src/windows/gss/gss-clie.c new file mode 100644 index 000000000..c567855c0 --- /dev/null +++ b/src/windows/gss/gss-clie.c @@ -0,0 +1,285 @@ +/* + * Copyright 1994 by OpenVision Technologies, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appears in all copies and + * that both that copyright notice and this permission notice appear in + * supporting documentation, and that the name of OpenVision not be used + * in advertising or publicity pertaining to distribution of the software + * without specific, written prior permission. OpenVision makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * OPENVISION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL OPENVISION BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF + * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +#include "gss.h" + +static const gss_OID_desc oids[] = { + {10, "\052\206\110\206\367\022\001\002\001\001"}, + {10, "\052\206\110\206\367\022\001\002\001\002"}, + {10, "\052\206\110\206\367\022\001\002\001\003"}, + {10, "\052\206\110\206\367\022\001\002\001\004"}, +}; + +const_gss_OID gss_nt_user_name = oids+0; +const_gss_OID gss_nt_machine_uid_name = oids+1; +const_gss_OID gss_nt_string_uid_name = oids+2; +const_gss_OID gss_nt_service_name = oids+3; + +int +gss (char *host, char *name, char *msg, u_short port) +{ + if (port == 0 || port == -1) + port = 4444; + + if (call_server(host, port, name, msg) < 0) + return 1; + + return 0; +} + +/*+ + * Function: call_server + * + * Purpose: Call the "sign" service. + * + * Arguments: + * + * host (r) the host providing the service + * port (r) the port to connect to on host + * service_name (r) the GSS-API service name to authenticate to + * msg (r) the message to have "signed" + * + * Returns: 0 on success, -1 on failure + * + * Effects: + * + * call_server opens a TCP connection to and establishes a + * GSS-API context with service_name over the connection. It then + * seals msg in a GSS-API token with gss_seal, sends it to the server, + * reads back a GSS-API signature block for msg from the server, and + * verifies it with gss_verify. -1 is returned if any step fails, + * otherwise 0 is returned. + */ +int +call_server (char *host, u_short port, char *service_name, char *msg) +{ + gss_ctx_id_t context; + gss_buffer_desc in_buf, out_buf; + int s, state; + OM_uint32 maj_stat, min_stat; + + /* Open connection */ + if ((s = connect_to_server(host, port)) < 0) + return -1; + + /* Establish context */ + if (client_establish_context(s, service_name, &context) < 0) + return -1; + + /* Seal the message */ + in_buf.value = msg; + in_buf.length = strlen(msg) + 1; + maj_stat = gss_seal(&min_stat, context, 1, GSS_C_QOP_DEFAULT, + &in_buf, &state, &out_buf); + if (maj_stat != GSS_S_COMPLETE) { + display_status("sealing message", maj_stat, min_stat); + return -1; + } else if (! state) { + OkMsgBox ("Warning! Message not encrypted.\n"); + } + + /* Send to server */ + if (send_token(s, &out_buf) < 0) + return -1; + (void) gss_release_buffer(&min_stat, &out_buf); + + /* Read signature block into out_buf */ + if (recv_token(s, &out_buf) < 0) + return -1; + + /* Verify signature block */ + maj_stat = gss_verify(&min_stat, context, &in_buf, &out_buf, &state); + if (maj_stat != GSS_S_COMPLETE) { + display_status("verifying signature", maj_stat, min_stat); + return -1; + } + (void) gss_release_buffer(&min_stat, &out_buf); + + OkMsgBox ("Signature verified."); + + /* Delete context */ + maj_stat = gss_delete_sec_context(&min_stat, &context, &out_buf); + if (maj_stat != GSS_S_COMPLETE) { + display_status("deleting context", maj_stat, min_stat); + return -1; + } + (void) gss_release_buffer(&min_stat, &out_buf); + + return 0; +} + +/*+ + * Function: connect_to_server + * + * Purpose: Opens a TCP connection to the name host and port. + * + * Arguments: + * + * host (r) the target host name + * port (r) the target port, in host byte order + * + * Returns: the established socket file desciptor, or -1 on failure + * + * Effects: + * + * The host name is resolved with gethostbyname(), and the socket is + * opened and connected. If an error occurs, an error message is + * displayed and -1 is returned. + */ +int +connect_to_server (char *host, u_short port) +{ + struct sockaddr_in saddr; + struct hostent *hp; + int s; + + if ((hp = gethostbyname(host)) == NULL) { + OkMsgBox ("Unknown host: %s\n", host); + return -1; + } + + saddr.sin_family = hp->h_addrtype; + memcpy((char *)&saddr.sin_addr, hp->h_addr, hp->h_length); + saddr.sin_port = htons(port); + + if ((s = socket(AF_INET, SOCK_STREAM, 0)) < 0) { + my_perror("creating socket"); + return -1; + } + if (connect(s, (struct sockaddr *)&saddr, sizeof(saddr)) < 0) { + my_perror("connecting to server"); + return -1; + } + return s; +} + +/*+ + * Function: client_establish_context + * + * Purpose: establishes a GSS-API context with a specified service and + * returns the context handle + * + * Arguments: + * + * s (r) an established TCP connection to the service + * sname (r) the ASCII service name of the service + * context (w) the established GSS-API context + * + * Returns: 0 on success, -1 on failure + * + * Effects: + * + * sname is imported as a GSS-API name and a GSS-API context is + * established with the corresponding service; the service should be + * listening on the TCP connection s. The default GSS-API mechanism + * is used, and mutual authentication and replay detection are + * requested. + * + * If successful, the context handle is returned in context. If + * unsuccessful, the GSS-API error messages are displayed on stderr + * and -1 is returned. + */ +int +client_establish_context (int s, char *sname, gss_ctx_id_t *gss_context) +{ + gss_buffer_desc send_tok, recv_tok, *token_ptr; + gss_name_t target_name; + OM_uint32 maj_stat, min_stat; + + /* + * Import the name into target_name. Use send_tok to save + * local variable space. + */ + send_tok.value = sname; + send_tok.length = strlen(sname) + 1; + maj_stat = gss_import_name(&min_stat, &send_tok, + gss_nt_service_name, &target_name); + if (maj_stat != GSS_S_COMPLETE) { + display_status("parsing name", maj_stat, min_stat); + return -1; + } + + /* + * Perform the context-establishement loop. + * + * On each pass through the loop, token_ptr points to the token + * to send to the server (or GSS_C_NO_BUFFER on the first pass). + * Every generated token is stored in send_tok which is then + * transmitted to the server; every received token is stored in + * recv_tok, which token_ptr is then set to, to be processed by + * the next call to gss_init_sec_context. + * + * GSS-API guarantees that send_tok's length will be non-zero + * if and only if the server is expecting another token from us, + * and that gss_init_sec_context returns GSS_S_CONTINUE_NEEDED if + * and only if the server has another token to send us. + */ + + token_ptr = GSS_C_NO_BUFFER; + *gss_context = GSS_C_NO_CONTEXT; + + do { + maj_stat = + gss_init_sec_context(&min_stat, + GSS_C_NO_CREDENTIAL, + gss_context, + target_name, + GSS_C_NULL_OID, + GSS_C_MUTUAL_FLAG | GSS_C_REPLAY_FLAG, + 0, + NULL, /* no channel bindings */ + token_ptr, + NULL, /* ignore mech type */ + &send_tok, + NULL, /* ignore ret_flags */ + NULL); /* ignore time_rec */ + + if (token_ptr != GSS_C_NO_BUFFER) + (void) gss_release_buffer(&min_stat, &recv_tok); + + if (maj_stat!=GSS_S_COMPLETE && maj_stat!=GSS_S_CONTINUE_NEEDED) { + display_status("initializing context", maj_stat, min_stat); + (void) gss_release_name(&min_stat, &target_name); + return -1; + } + + if (send_tok.length != 0) { + if (send_token(s, &send_tok) < 0) { + (void) gss_release_buffer(&min_stat, &send_tok); + (void) gss_release_name(&min_stat, &target_name); + return -1; + } + } + (void) gss_release_buffer(&min_stat, &send_tok); + + if (maj_stat == GSS_S_CONTINUE_NEEDED) { + if (recv_token(s, &recv_tok) < 0) { + (void) gss_release_name(&min_stat, &target_name); + return -1; + } + token_ptr = &recv_tok; + } + } while (maj_stat == GSS_S_CONTINUE_NEEDED); + + (void) gss_release_name(&min_stat, &target_name); + return 0; +} diff --git a/src/windows/gss/gss-misc.c b/src/windows/gss/gss-misc.c new file mode 100644 index 000000000..fc41a834d --- /dev/null +++ b/src/windows/gss/gss-misc.c @@ -0,0 +1,196 @@ +/* + * Copyright 1994 by OpenVision Technologies, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appears in all copies and + * that both that copyright notice and this permission notice appear in + * supporting documentation, and that the name of OpenVision not be used + * in advertising or publicity pertaining to distribution of the software + * without specific, written prior permission. OpenVision makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * OPENVISION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL OPENVISION BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF + * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +#include "gss.h" +#include +#include + +/*+ + * Function: send_token + * + * Purpose: Writes a token to a file descriptor. + * + * Arguments: + * + * s (r) an open file descriptor + * tok (r) the token to write + * + * Returns: 0 on success, -1 on failure + * + * Effects: + * + * send_token writes the token length (as a network long) and then the + * token data to the file descriptor s. It returns 0 on success, and + * -1 if an error occurs or if it could not write all the data. + */ +int send_token(int s, gss_buffer_t tok) { + long len; + size_t ret; + + len = htonl(tok->length); + + ret = send (s, (char *) &len, 4, 0); // Send length over the socket + if (ret < 0) { + my_perror("sending token length"); + return -1; + } else if (ret != 4) { + OkMsgBox ("sending token length: %d of %d bytes written\n", + ret, 4); + return -1; + } + + ret = send (s, tok->value, tok->length, 0); // Send the data + if (ret < 0) { + my_perror("sending token data"); + return -1; + } else if (ret != tok->length) { + OkMsgBox ("sending token data: %d of %d bytes written\n", + ret, tok->length); + return -1; + } + + return 0; +} + +/*+ + * Function: recv_token + * + * Purpose: Reads a token from a file descriptor. + * + * Arguments: + * + * s (r) an open file descriptor + * tok (w) the read token + * + * Returns: 0 on success, -1 on failure + * + * Effects: + * + * recv_token reads the token length (as a network long), allocates + * memory to hold the data, and then reads the token data from the + * file descriptor s. It blocks to read the length and data, if + * necessary. On a successful return, the token should be freed with + * gss_release_buffer. It returns 0 on success, and -1 if an error + * occurs or if it could not read all the data. + */ +int +recv_token (int s, gss_buffer_t tok) { + int ret; + unsigned long len; + + ret = recv (s, (char *) &tok->length, 4, 0); + if (ret < 0) { + my_perror("reading token length"); + return -1; + } else if (ret != 4) { + OkMsgBox ("reading token length: %d of %d bytes read\n", + ret, 4); + return -1; + } + + len = ntohl(tok->length); + tok->length = (size_t) len; + tok->value = (char *) malloc(tok->length); + if (tok->value == NULL) { + OkMsgBox ("Out of memory allocating token data\n"); + return -1; + } + + ret = recv (s, (char *) tok->value, tok->length, 0); + if (ret < 0) { + my_perror("reading token data"); + free(tok->value); + return -1; + } else if ((size_t) ret != tok->length) { + OkMsgBox ("sending token data: %d of %d bytes written\n", + ret, tok->length); + free(tok->value); + return -1; + } + + return 0; +} + +/*+ + * Function: display_status + * + * Purpose: displays GSS-API messages + * + * Arguments: + * + * msg a string to be displayed with the message + * maj_stat the GSS-API major status code + * min_stat the GSS-API minor status code + * + * Effects: + * + * The GSS-API messages associated with maj_stat and min_stat are + * displayed on stderr, each preceeded by "GSS-API error : " and + * followed by a newline. + */ +void +display_status (char *msg, OM_uint32 maj_stat, OM_uint32 min_stat) { + display_status_1(msg, maj_stat, GSS_C_GSS_CODE); + display_status_1(msg, min_stat, GSS_C_MECH_CODE); +} + +static void +display_status_1(char *m, OM_uint32 code, int type) { + OM_uint32 maj_stat, min_stat; + gss_buffer_desc msg; + int msg_ctx; + + msg_ctx = 0; + while (1) { + maj_stat = gss_display_status(&min_stat, code, + type, GSS_C_NULL_OID, + &msg_ctx, &msg); + OkMsgBox ("GSS-API error %s: %s\n", m, + (char *)msg.value); + (void) gss_release_buffer(&min_stat, &msg); + + if (!msg_ctx) + break; + } +} + +void +OkMsgBox (char *format, ...) { + char buf[256]; // Message goes into here + char *args; // Args for printf + + args = (char *) &format + sizeof(format); + vsprintf (buf, format, args); + MessageBox(NULL, buf, NULL, MB_OK); +} + +void +my_perror (char *msg) { + char *err; + + err = strerror (errno); + + if (msg && *msg != '\0') + OkMsgBox ("%s: %s", msg, err); + else + MessageBox (NULL, err, "", MB_OK); +} diff --git a/src/windows/gss/gss.c b/src/windows/gss/gss.c new file mode 100644 index 000000000..9a8e12237 --- /dev/null +++ b/src/windows/gss/gss.c @@ -0,0 +1,132 @@ +/*+************************************************************************* +** +** GSS test - Windows scaffolding to test the gssapi dll +** +** Given a hostname it does the equivalent of the Unix command +** ./gss-client host@ "msg" +** +***************************************************************************/ + +#include +#include +#include "gss.h" + +#define GSS_CONNECT_NAME 102 +#define GSS_OK 100 +#define GSS_CANCEL 101 + +char szConnectName[256]; +char szServiceName[256]; + +int PASCAL +WinMain (hInstance, hPrevInstance, lpszCmdLine, nCmdShow) +HANDLE hInstance, hPrevInstance; +LPSTR lpszCmdLine; +int nCmdShow; +{ + int n; // Return value + FARPROC lpfnDlgProc; + + lpfnDlgProc = MakeProcInstance(OpenGssapiDlg, hInstance); + n = DialogBox (hInstance, "OPENGSSAPIDLG", NULL, lpfnDlgProc); + FreeProcInstance(lpfnDlgProc); + + if (n) { + strcpy (szServiceName, "host@"); + strcat (szServiceName, szConnectName); + n = gss (szConnectName, szServiceName, "Test Gssapi Message", 0); + if (n) + MessageBox (NULL, "gss failed", "", IDOK | MB_ICONINFORMATION); + } + + return 0; +} + +/*+*************************************************************************** + + FUNCTION: OpenGssapiDlg(HWND, unsigned, WORD, LONG) + + PURPOSE: Processes messages for "Open Gssapi Connection" dialog box + + MESSAGES: + + WM_INITDIALOG - initialize dialog box + WM_COMMAND - Input received + +****************************************************************************/ + +BOOL FAR PASCAL OpenGssapiDlg( + HWND hDlg, + WORD message, + WORD wParam, + LONG lParam) +{ + HDC hDC; + int xExt, yExt; + DWORD Ext; +// HWND hEdit; +// int n; +// int iHostNum = 0; +// char tmpName[128]; +// char tmpBuf[80]; +// char *tmpCommaLoc; + + switch (message) { + + case WM_INITDIALOG: + hDC = GetDC(hDlg); + Ext = GetDialogBaseUnits(); + xExt = (190 *LOWORD(Ext)) /4 ; + yExt = (72 * HIWORD(Ext)) /8 ; + SetWindowPos(hDlg, NULL, + (GetSystemMetrics(SM_CXSCREEN)/2)-(xExt/2), + (GetSystemMetrics(SM_CYSCREEN)/2)-(yExt/2), + 0, 0, SWP_NOSIZE | SWP_NOZORDER | SWP_SHOWWINDOW); + ReleaseDC(hDlg, hDC); +// GetPrivateProfileString(INI_HOSTS, INI_HOST "0", "", tmpName, +// 128, TELNET_INI); +// if (tmpName[0]) { +// tmpCommaLoc = strchr(tmpName, ','); +// if (tmpCommaLoc) +// *tmpCommaLoc = '\0'; +// SetDlgItemText(hDlg, GSS_CONNECT_NAME, tmpName); +// } +// hEdit = GetWindow(GetDlgItem(hDlg, GSS_CONNECT_NAME), GW_CHILD); +// while (TRUE) { +// wsprintf(tmpBuf, INI_HOST "%d", iHostNum++); +// GetPrivateProfileString(INI_HOSTS, tmpBuf, "", tmpName, +// 128, TELNET_INI); +// tmpCommaLoc = strchr(tmpName, ','); +// if (tmpCommaLoc) +// *tmpCommaLoc = '\0'; +// if (tmpName[0]) +// SendDlgItemMessage(hDlg, GSS_CONNECT_NAME, CB_ADDSTRING, 0, +// (LPARAM) ((LPSTR) tmpName)); +// else +// break; +// } +// SendMessage(hEdit, WM_USER+1, NULL, NULL); + SendMessage(hDlg, WM_SETFOCUS, NULL, NULL); + return (TRUE); + + case WM_COMMAND: + switch (wParam) { + case GSS_CANCEL: + EndDialog(hDlg, FALSE); + break; + + case GSS_OK: + GetDlgItemText(hDlg, GSS_CONNECT_NAME, szConnectName, 256); + if (! *szConnectName) { + MessageBox(hDlg, "You must enter a host name", + NULL, MB_OK); + break; + } + EndDialog(hDlg, TRUE); + break; + } + return (FALSE); + } + return(FALSE); + +} /* OpenGssapiDlg */ diff --git a/src/windows/gss/gss.def b/src/windows/gss/gss.def new file mode 100644 index 000000000..f49806698 --- /dev/null +++ b/src/windows/gss/gss.def @@ -0,0 +1,15 @@ +; +; Gss - tests the GSSAPI dll +; + +NAME GSS +DESCRIPTION 'Tests the gssapi dll' + +EXETYPE windows +STUB 'winstub.exe' +CODE preload moveable +DATA preload moveable multiple +HEAPSIZE 1024 +STACKSIZE 4096 + +EXPORTS OpenGssapiDlg diff --git a/src/windows/gss/gss.h b/src/windows/gss/gss.h new file mode 100644 index 000000000..5a943fb10 --- /dev/null +++ b/src/windows/gss/gss.h @@ -0,0 +1,29 @@ +/*+************************************************************************* +** +** gss.h +** +** +***************************************************************************/ +#include +#include "winsock.h" +#include + +#include +#include + +// gss.c +BOOL FAR PASCAL OpenGssapiDlg(HWND hDlg, WORD message, WORD wParam, LONG lParam); + +// gss-misc.c +int send_token(int s, gss_buffer_t tok); +int recv_token(int s, gss_buffer_t tok); +void display_status(char *msg, OM_uint32 maj_stat, OM_uint32 min_stat); +static void display_status_1(char *m, OM_uint32 code, int type); +void OkMsgBox (char *format, ...); +void my_perror (char *msg); + +// gss-client.c +int gss (char *host, char *name, char *msg, u_short port); +int call_server(char *host, u_short port, char *service_name, char *msg); +int connect_to_server(char *host, u_short port); +int client_establish_context(int s, char *service_name, gss_ctx_id_t *gss_context); diff --git a/src/windows/gss/gss.ico b/src/windows/gss/gss.ico new file mode 100644 index 000000000..8cd96a18a Binary files /dev/null and b/src/windows/gss/gss.ico differ diff --git a/src/windows/gss/gss.rc b/src/windows/gss/gss.rc new file mode 100644 index 000000000..cd968844b --- /dev/null +++ b/src/windows/gss/gss.rc @@ -0,0 +1,27 @@ +/*+************************************************************************* +** +** Gss +** +** Tests the gssapi dll. +** +***************************************************************************/ + +#include + +#define GSS_CONNECT_NAME 102 +#define GSS_OK 100 +#define GSS_CANCEL 101 + +OPENGSSAPIDLG DIALOG 63, 65, 175, 51 +STYLE DS_ABSALIGN | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION "Open GSSAPI Connection" +FONT 8, "MS Sans Serif" +BEGIN + CONTROL "To Host:", -1, "STATIC", NOT WS_GROUP, 3, 10, 33, 10 + CONTROL "", GSS_CONNECT_NAME, "COMBOBOX", CBS_DROPDOWN | WS_VSCROLL | WS_GROUP | WS_TABSTOP, 42, 9, 128, 60 + CONTROL "OK", GSS_OK, "BUTTON", WS_GROUP | WS_TABSTOP | BS_DEFPUSHBUTTON, 27, 30, 51, 14 + CONTROL "Cancel", GSS_CANCEL, "BUTTON", WS_TABSTOP, 97, 30, 51, 14 +END + + + diff --git a/src/windows/gss/makefile b/src/windows/gss/makefile new file mode 100644 index 000000000..cf784e717 --- /dev/null +++ b/src/windows/gss/makefile @@ -0,0 +1,58 @@ +# makefile: Constructs the Kerberos for Windows ticket manager +# Works for both k4 and k5 releases. +# +NAME = gss +OBJS = gss.obj gss-client.obj gss-misc.obj + +##### Options +DEBUG = 1 +BUILDTOP =..\.. +LIBDIR = $(BUILDTOP)\lib +GLIB = $(LIBDIR)\gssapi.lib +WLIB = $(LIBDIR)\winsock.lib +INCLUDES = /I$(BUILDTOP)\include /I$(BUILDTOP)\include\krb5 + +##### C Compiler +CC = cl +CFLAGS_RELEASE = /nologo /W3 /AL /GAs /Gy /G2 /Zp /O2 /DNDEBUG=1 +CFLAGS_DEBUG = /nologo /W3 /AL /GAs /Gy /G2 /Zp /O2 /Od /Zi +!if $(DEBUG) +CFLAGS = $(CFLAGS_DEBUG) $(INCLUDES) +!else +CFLAGS = $(CFLAGS_RELEASE) $(INCLUDES) +!endif + +##### RC Compiler +RC = rc +RFLAGS = /nologo $(INCLUDES) + +##### Linker +LINK = link +LIBS = $(GLIB) $(WLIB) +SYSLIBS = libw llibcew +!if $(DEBUG) +LFLAGS = /co /nologo /nod /nopackcode /map:full +!else +LFLAGS = /nologo /nod /nopackcode +!endif + +all:: makefile $(NAME).exe + +$(NAME).exe: $*.def $*.res $(OBJS) $(LIBS) + $(LINK) $(LFLAGS) $(OBJS), $@, $*.map, $(LIBS) $(SYSLIBS), $*.def + $(RC) $(RFLAGS) /k $*.res $@ + +$(OBJS) $(NAME).res: gss.h + +install: + copy gss.exe ..\floppy + +clean:: + if exist *.exe del *.exe + if exist ..\floppy\gss.exe del ..\floppy\gss.exe + if exist *.obj del *.obj + if exist *.res del *.res + if exist *.map del *.map + if exist *.pdb del *.pdb + if exist *.err del *.err + diff --git a/src/windows/makefile b/src/windows/makefile index 80163378f..059b60b64 100644 --- a/src/windows/makefile +++ b/src/windows/makefile @@ -8,6 +8,9 @@ all:: @echo Making in windows\wintel cd ..\wintel -$(MAKE) -$(MAKEFLAGS) LIBCMD=$(LIBCMD) + @echo Making in windows\gss + cd ..\gss + -$(MAKE) -$(MAKEFLAGS) LIBCMD=$(LIBCMD) cd .. clean:: @@ -17,5 +20,8 @@ clean:: @echo Making clean in windows\wintel cd ..\wintel -$(MAKE) -$(MAKEFLAGS) clean + @echo Making clean in windows\gss + cd ..\gss + -$(MAKE) -$(MAKEFLAGS) clean cd ..