summaryrefslogtreecommitdiffstats
path: root/misc/netware/start.c
blob: 76817d96c00e74b28c571f0c8d8da534225b3f98 (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
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
/* Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You 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"
#include "apr_ldap.h"            /* for apr_ldap_rebind_init() */

#ifdef USE_WINSOCK
/* Prototypes missing from older NDKs */
int WSAStartupRTags(WORD wVersionRequested,
                    LPWSADATA lpWSAData,
                    rtag_t WSAStartupRTag,
                    rtag_t WSPSKTRTag,
                    rtag_t lookUpServiceBeginRTag,
                    rtag_t WSAEventRTag,
                    rtag_t WSPCPRTag);

int WSACleanupRTag(rtag_t rTag);

/*
** 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;
}
#endif



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;
    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");

#ifdef USE_WINSOCK
    {
        int err;
        if ((err = RegisterAppWithWinSock (nlmhandle))) {
            return err;
        }
    }
#endif

    apr_signal_init(pool);
#if APR_HAS_LDAP
    apr_ldap_rebind_init(pool);
#endif

    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 ();

#ifdef USE_WINSOCK
    UnregisterAppWithWinSock (app_data->gs_nlmhandle);
#endif
}

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