summaryrefslogtreecommitdiff
path: root/misc/netware/start.c
blob: d359c3de41e095f2badc3706b074239a6e831680 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
/* Copyright 2000-2005 The Apache Software Foundation or its licensors, as
 * applicable.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "apr.h"
#include "apr_general.h"
#include "apr_pools.h"
#include "apr_signal.h"

#include "apr_arch_misc.h"       /* for WSAHighByte / WSALowByte */
#include "apr_arch_proc_mutex.h" /* for apr_proc_mutex_unix_setup_lock() */
#include "apr_arch_internal_time.h"

/*
** Resource tag signatures for using NetWare WinSock 2. These will no longer
** be needed by anyone once the new WSAStartupWithNlmHandle() is available
** since WinSock will make the calls to AllocateResourceTag().
*/
#define WS_LOAD_ENTRY_SIGNATURE     (*(unsigned long *) "WLDE")
#define WS_SKT_SIGNATURE            (*(unsigned long *) "WSKT")
#define WS_LOOKUP_SERVICE_SIGNATURE (*(unsigned long *) "WLUP")
#define WS_WSAEVENT_SIGNATURE       (*(unsigned long *) "WEVT")
#define WS_CPORT_SIGNATURE          (*(unsigned long *) "WCPT")


int (*WSAStartupWithNLMHandle)( WORD version, LPWSADATA data, void *handle ) = NULL;
int (*WSACleanupWithNLMHandle)( void *handle ) = NULL;

static int wsa_startup_with_handle (WORD wVersionRequested, LPWSADATA data, void *handle)
{
    APP_DATA *app_data;
    
    if (!(app_data = (APP_DATA*) get_app_data(gLibId)))
        return APR_EGENERAL;

    app_data->gs_startup_rtag = AllocateResourceTag(handle, "WinSock Start-up", WS_LOAD_ENTRY_SIGNATURE);
    app_data->gs_socket_rtag  = AllocateResourceTag(handle, "WinSock socket()", WS_SKT_SIGNATURE);
    app_data->gs_lookup_rtag  = AllocateResourceTag(handle, "WinSock Look-up", WS_LOOKUP_SERVICE_SIGNATURE);
    app_data->gs_event_rtag   = AllocateResourceTag(handle, "WinSock Event", WS_WSAEVENT_SIGNATURE);
    app_data->gs_pcp_rtag     = AllocateResourceTag(handle, "WinSock C-Port", WS_CPORT_SIGNATURE);

    return WSAStartupRTags(wVersionRequested, data, 
                           app_data->gs_startup_rtag, 
                           app_data->gs_socket_rtag, 
                           app_data->gs_lookup_rtag, 
                           app_data->gs_event_rtag, 
                           app_data->gs_pcp_rtag);
}

static int wsa_cleanup_with_handle (void *handle)
{
    APP_DATA *app_data;
    
    if (!(app_data = (APP_DATA*) get_app_data(gLibId)))
        return APR_EGENERAL;

    return WSACleanupRTag(app_data->gs_startup_rtag);
}

static int UnregisterAppWithWinSock (void *nlm_handle)
{
    if (!WSACleanupWithNLMHandle)
    {
        if (!(WSACleanupWithNLMHandle = ImportPublicObject(gLibHandle, "WSACleanupWithNLMHandle")))
            WSACleanupWithNLMHandle = wsa_cleanup_with_handle;
    }

    return (*WSACleanupWithNLMHandle)(nlm_handle);
}

static int RegisterAppWithWinSock (void *nlm_handle)
{
    int err;
    WSADATA wsaData;
    WORD wVersionRequested = MAKEWORD(WSAHighByte, WSALowByte);

    if (!WSAStartupWithNLMHandle)
    {
        if (!(WSAStartupWithNLMHandle = ImportPublicObject(gLibHandle, "WSAStartupWithNLMHandle")))
            WSAStartupWithNLMHandle = wsa_startup_with_handle;
    }

    err = (*WSAStartupWithNLMHandle)(wVersionRequested, &wsaData, nlm_handle);

    if (LOBYTE(wsaData.wVersion) != WSAHighByte ||
        HIBYTE(wsaData.wVersion) != WSALowByte) {
        
        UnregisterAppWithWinSock (nlm_handle);
        return APR_EEXIST;
    }

    return err;
}



APR_DECLARE(apr_status_t) apr_app_initialize(int *argc, 
                                             const char * const * *argv, 
                                             const char * const * *env)
{
    /* An absolute noop.  At present, only Win32 requires this stub, but it's
     * required in order to move command arguments passed through the service
     * control manager into the process, and it's required to fix the char*
     * data passed in from win32 unicode into utf-8, win32's apr internal fmt.
     */
    return apr_initialize();
}

APR_DECLARE(apr_status_t) apr_initialize(void)
{
    apr_pool_t *pool;
    int err;
    void *nlmhandle = getnlmhandle();

    /* Register the NLM as using APR. If it is already
        registered then just return. */
    if (register_NLM(nlmhandle) != 0) {
        return APR_SUCCESS;
    }

    /* apr_pool_initialize() is being called from the library
        startup code since all of the memory resources belong 
        to the library rather than the application. */
    
    if (apr_pool_create(&pool, NULL) != APR_SUCCESS) {
        return APR_ENOPOOL;
    }

    apr_pool_tag(pool, "apr_initilialize");

    err = RegisterAppWithWinSock (nlmhandle);
    
    if (err) {
        return err;
    }

    apr_signal_init(pool);

    return APR_SUCCESS;
}

APR_DECLARE_NONSTD(void) apr_terminate(void)
{
    APP_DATA *app_data;

    /* Get our instance data for shutting down. */
    if (!(app_data = (APP_DATA*) get_app_data(gLibId)))
        return;

    /* Unregister the NLM. If it is not registered
        then just return. */
    if (unregister_NLM(app_data->gs_nlmhandle) != 0) {
        return;
    }

    /* apr_pool_terminate() is being called from the 
        library shutdown code since the memory resources
        belong to the library rather than the application */

    /* Just clean up the memory for the app that is going
        away. */
    netware_pool_proc_cleanup ();

    UnregisterAppWithWinSock (app_data->gs_nlmhandle);
}

APR_DECLARE(void) apr_terminate2(void)
{
    apr_terminate();
}