1/* 2 * Copyright 1990 Network Computing Devices; 3 * Portions Copyright 1987 by Digital Equipment Corporation 4 * 5 * Permission to use, copy, modify, distribute, and sell this software 6 * and its documentation for any purpose is hereby granted without fee, 7 * provided that the above copyright notice appear in all copies and 8 * that both that copyright notice and this permission notice appear 9 * in supporting documentation, and that the names of Network Computing 10 * Devices or Digital not be used in advertising or publicity pertaining 11 * to distribution of the software without specific, written prior 12 * permission. Network Computing Devices or Digital make no representations 13 * about the suitability of this software for any purpose. It is provided 14 * "as is" without express or implied warranty. 15 * 16 * NETWORK COMPUTING DEVICES AND DIGITAL DISCLAIM ALL WARRANTIES WITH 17 * REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF 18 * MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL NETWORK COMPUTING DEVICES 19 * OR DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES 20 * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, 21 * WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, 22 * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS 23 * SOFTWARE. 24 */ 25 26/* 27 28Copyright 1987, 1994, 1998 The Open Group 29 30Permission to use, copy, modify, distribute, and sell this software and its 31documentation for any purpose is hereby granted without fee, provided that 32the above copyright notice appear in all copies and that both that 33copyright notice and this permission notice appear in supporting 34documentation. 35 36The above copyright notice and this permission notice shall be included in 37all copies or substantial portions of the Software. 38 39THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 40IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 41FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 42OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 43AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 44CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 45 46Except as contained in this notice, the name of The Open Group shall not be 47used in advertising or otherwise to promote the sale, use or other dealings 48in this Software without prior written authorization from The Open Group. 49 50*/ 51 52#ifdef HAVE_CONFIG_H 53#include <config.h> 54#endif 55#include "FSlibint.h" 56#include <stdio.h> 57#include "X11/Xpoll.h" 58#ifdef WIN32 59#define ECHECK(err) (WSAGetLastError() == err) 60#else 61#define ECHECK(err) (errno == err) 62#endif 63 64/* 65 * Attempts to connect to server, given server name. Returns transport 66 * connection object or NULL if connection fails. 67 */ 68 69#define FS_CONNECTION_RETRIES 5 70 71XtransConnInfo 72_FSConnectServer(char *server_name) 73{ 74 XtransConnInfo trans_conn = NULL; /* transport connection object */ 75 int retry, connect_stat; 76 int madeConnection = 0; 77 78 /* 79 * Open the network connection. 80 */ 81 82 for (retry = FS_CONNECTION_RETRIES; retry >= 0; retry--) 83 { 84 if ((trans_conn = _FSTransOpenCOTSClient(server_name)) == NULL) 85 { 86 break; 87 } 88 89 if ((connect_stat = _FSTransConnect(trans_conn,server_name)) < 0) 90 { 91 _FSTransClose(trans_conn); 92 93 if (connect_stat == TRANS_TRY_CONNECT_AGAIN) 94 { 95 sleep(1); 96 continue; 97 } 98 else 99 break; 100 } 101 else 102 { 103 madeConnection = 1; 104 break; 105 } 106 } 107 108 if (!madeConnection) 109 return (NULL); 110 111 112 /* 113 * set it non-blocking. This is so we can read data when blocked for 114 * writing in the library. 115 */ 116 117 _FSTransSetOption(trans_conn, TRANS_NONBLOCKING, 1); 118 119 return (trans_conn); 120} 121 122/* 123 * Disconnect from server. 124 */ 125 126void 127_FSDisconnectServer(XtransConnInfo trans_conn) 128 129{ 130 (void) _FSTransClose(trans_conn); 131} 132 133 134/* 135 * This is an OS dependent routine which: 136 * 1) returns as soon as the connection can be written on.... 137 * 2) if the connection can be read, must enqueue events and handle errors, 138 * until the connection is writable. 139 */ 140void _FSWaitForWritable(FSServer *svr) 141{ 142 fd_set r_mask; 143 fd_set w_mask; 144 int nfound; 145 146 FD_ZERO(&r_mask); 147 FD_ZERO(&w_mask); 148 149 while (1) { 150 FD_SET(svr->fd, &r_mask); 151 FD_SET(svr->fd, &w_mask); 152 153 do { 154 nfound = Select(svr->fd + 1, &r_mask, &w_mask, NULL, NULL); 155 if (nfound < 0 && !ECHECK(EINTR)) 156 (*_FSIOErrorFunction) (svr); 157 } while (nfound <= 0); 158 159 if (XFD_ANYSET(&r_mask)) { 160 char buf[BUFSIZE]; 161 BytesReadable_t pend_not_register; 162 register BytesReadable_t pend; 163 register fsEvent *ev; 164 165 /* find out how much data can be read */ 166 if (_FSTransBytesReadable(svr->trans_conn, &pend_not_register) < 0) 167 (*_FSIOErrorFunction) (svr); 168 pend = pend_not_register; 169 170 /* 171 * must read at least one fsEvent; if none is pending, then we'll 172 * just block waiting for it 173 */ 174 if (pend < SIZEOF(fsEvent)) 175 pend = SIZEOF(fsEvent); 176 177 /* but we won't read more than the max buffer size */ 178 if (pend > BUFSIZE) 179 pend = BUFSIZE; 180 181 /* round down to an integral number of FSReps */ 182 pend = (pend / SIZEOF(fsEvent)) * SIZEOF(fsEvent); 183 184 _FSRead(svr, buf, pend); 185 186 /* no space between comma and type or else macro will die */ 187 STARTITERATE(ev, fsEvent, buf, (pend > 0), 188 (pend -= SIZEOF(fsEvent))) { 189 if (ev->type == FS_Error) 190 _FSError(svr, (fsError *) ev); 191 else /* it's an event packet; enqueue it */ 192 _FSEnq(svr, ev); 193 } 194 ENDITERATE 195 } 196 if (XFD_ANYSET(&w_mask)) 197 return; 198 } 199} 200 201 202void _FSWaitForReadable(FSServer *svr) 203{ 204 fd_set r_mask; 205 int result; 206 207 FD_ZERO(&r_mask); 208 do { 209 FD_SET(svr->fd, &r_mask); 210 result = Select(svr->fd + 1, &r_mask, NULL, NULL, NULL); 211 if (result == -1 && !ECHECK(EINTR)) 212 (*_FSIOErrorFunction) (svr); 213 } while (result <= 0); 214} 215 216void _FSSendClientPrefix( 217 FSServer *svr, 218 fsConnClientPrefix *client) 219{ 220 struct iovec iovarray[5], 221 *iov = iovarray; 222 int niov = 0; 223 224#define add_to_iov(b,l) \ 225 { iov->iov_base = (b); iov->iov_len = (l); iov++, niov++; } 226 227 add_to_iov((caddr_t) client, SIZEOF(fsConnClientPrefix)); 228 229#undef add_to_iov 230 231 (void) _FSTransWritev(svr->trans_conn, iovarray, niov); 232 return; 233} 234