sockets.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369
  1. /* sockets.c Copyright (C) 1995 NAG Ltd */
  2. /*
  3. * Functions to support operations on sockets for AXIOM: basically just
  4. * interfaces to some of the functions in libspad.a (sockio-c.c). We
  5. * assume that all integers returned as Lisp objects can be represented
  6. * as CCL fixnums, i.e. do not lie in the range +/-(2^28 .. 2^32-1).
  7. *
  8. * Version 1.0 September 1995
  9. *
  10. * Author: Mike Dewar
  11. *
  12. */
  13. /* Signature: 77381795 08-Apr-2002 */
  14. #include <stdarg.h>
  15. #include <sys/types.h>
  16. #include <string.h>
  17. #ifdef __WATCOMC__
  18. #include <dos.h>
  19. #endif
  20. #include "machine.h"
  21. #include "tags.h"
  22. #include "cslerror.h"
  23. #include "externs.h"
  24. #include "arith.h"
  25. #if defined(UNIX) && !defined(NoSockets)
  26. #define RealSockets
  27. #endif
  28. #ifdef FLEX
  29. /* we don't use timers; we call timnag in gc.c explicitly for UNIX */
  30. static int got_license =0;
  31. void init_lm()
  32. {
  33. extern void glnag(char *prod_code, char *user_opts);
  34. extern void rlnag();
  35. /* If glnag fails it calls displmmsg and exits */
  36. if (got_license == 0) {
  37. #if defined(__alpha)
  38. glnag("AXDAU21NA","");
  39. #elif defined(__SVR4) && defined(__sparc)
  40. #if defined(__GNUC__)
  41. glnag("AXSOL21NB","");
  42. #else
  43. glnag("AXSOL21NA","");
  44. #endif
  45. #elif (defined(sparc) || defined(__sparc)) && !defined(__SVR4)
  46. glnag("AXSU421NA","");
  47. #elif defined(__hp9000s800)
  48. glnag("AXH9721NA","");
  49. #elif defined(__sgi) && defined(__mips) && __mips==1
  50. glnag("AXSG521NA","");
  51. #elif defined(__sgi) && defined(__mips) && __mips==3
  52. glnag("AXSG621NA","");
  53. #elif defined(_AIX)
  54. glnag("AXIB621NA","");
  55. #elif defined(__linux__)
  56. glnag("AXLUX21NA","");
  57. #elif defined(WINDOWS_NT)
  58. glnag("AXW3222NA","");
  59. #ifndef CWIN
  60. #endif
  61. rlnag();
  62. #endif
  63. got_license = 1;
  64. }
  65. }
  66. void close_lm()
  67. {
  68. #ifdef WINDOWS_NT
  69. extern void rlnag();
  70. if (got_license) {
  71. rlnag();
  72. got_license = 0;
  73. }
  74. #endif
  75. }
  76. Lisp_Object Linit_lm(Lisp_Object nil, Lisp_Object dummy)
  77. {
  78. init_lm();
  79. return onevalue(fixnum_of_int(1));
  80. }
  81. #ifdef CWIN
  82. #undef exit
  83. #endif
  84. void displmmsg(int unlicensed, char *message)
  85. {
  86. /* term_printf only handles strings less than 256 characters long */
  87. if (strlen(message) > 255) {
  88. char *line;
  89. line = strtok(message,"\n");
  90. term_printf("%s\n",line);
  91. while ((line=strtok(NULL,"\n")) != NULL) term_printf("%s\n",line);
  92. }
  93. else
  94. term_printf("%s\n",message);
  95. #ifdef CWIN
  96. ensure_screen();
  97. #endif
  98. if (unlicensed > 0) {
  99. term_printf("+++ This copy of AXIOM is unlicensed ... exiting.\n");
  100. #ifdef CWIN
  101. ensure_screen();
  102. #endif
  103. sleep(10);
  104. my_exit(2);
  105. }
  106. }
  107. Lisp_Object MS_CDECL Lclose_lm(Lisp_Object nil, int32 nargs, ...)
  108. {
  109. argcheck(nargs,0,"close-lm");
  110. close_lm();
  111. return nil;
  112. }
  113. #else
  114. Lisp_Object Linit_lm(Lisp_Object nil, Lisp_Object dummy)
  115. {
  116. return onevalue(fixnum_of_int(1));
  117. }
  118. Lisp_Object MS_CDECL Lclose_lm(Lisp_Object nil, int32 nargs, ...)
  119. {
  120. argcheck(nargs,0,"close-lm");
  121. return nil;
  122. }
  123. #endif
  124. #ifdef RealSockets
  125. /* These are all in sockio-c.c */
  126. extern int32 open_server(char *server_name);
  127. extern int32 sock_get_int(int32 purpose);
  128. extern int32 sock_send_int(int32 purpose, int32 val);
  129. extern char *sock_get_string_buf(int32 purpose, char *buf, int32 buf_len);
  130. extern int32 sock_send_string_len(int32 purpose, char *str, int32 len);
  131. extern double sock_get_float(int32 purpose);
  132. extern int32 sock_send_float(int32 purpose, double num);
  133. extern int32 sock_send_wakeup(int32 purpose);
  134. extern int32 server_switch();
  135. extern int32 flush_stdout();
  136. extern int32 sock_send_signal(int purpose, int sig);
  137. extern int32 print_line(char *s);
  138. /* Utility function to test for CCL integers and turn them into C ints */
  139. int32 ccl2int(Lisp_Object i, char *fcn)
  140. { if (is_fixnum(i))
  141. return (int_of_fixnum(i));
  142. else if (is_numbers(i) && is_bignum(i) )
  143. return (thirty_two_bits(i));
  144. else
  145. return aerror(fcn);
  146. }
  147. Lisp_Object LopenServer(Lisp_Object nil, Lisp_Object server)
  148. {
  149. if (!(is_vector(server) && type_of_header(vechdr(server)) == TYPE_STRING) )
  150. return aerror("open_server");
  151. else
  152. return onevalue(fixnum_of_int(open_server(&celt(server,0))));
  153. }
  154. Lisp_Object LsockGetInt(Lisp_Object nil, Lisp_Object purpose)
  155. {
  156. return onevalue(fixnum_of_int(sock_get_int(ccl2int(purpose,"sock_get_int"))));
  157. }
  158. Lisp_Object LsockSendInt(Lisp_Object nil, Lisp_Object purpose, Lisp_Object val)
  159. {
  160. return onevalue(fixnum_of_int(
  161. sock_send_int(ccl2int(purpose,"sock_send_int"),
  162. ccl2int(val,"sock_send_int"))));
  163. }
  164. Lisp_Object MS_CDECL LsockGetStringBuf(Lisp_Object nil, int nargs, ...)
  165. {
  166. va_list args;
  167. Lisp_Object purpose, buf, buf_length;
  168. argcheck(nargs,3,"sock_get_string_buf");
  169. va_start(args,nargs);
  170. purpose = va_arg(args, Lisp_Object);
  171. buf = va_arg(args, Lisp_Object);
  172. buf_length = va_arg(args, Lisp_Object);
  173. va_end(args);
  174. if (!(is_vector(buf) && type_of_header(vechdr(buf)) == TYPE_STRING) )
  175. aerror("sock_get_string_buf");
  176. else
  177. sock_get_string_buf(ccl2int(purpose,"sock_get_string_buf"),
  178. &celt(buf,0),
  179. ccl2int(buf_length,"sock_get_string_buf") );
  180. /* AXIOM always ignores the return value */
  181. return buf;
  182. }
  183. Lisp_Object MS_CDECL LsockSendStringLen(Lisp_Object nil, int nargs, ...)
  184. {
  185. va_list args;
  186. Lisp_Object purpose, buf, buf_length;
  187. argcheck(nargs,3,"sock_send_string_len");
  188. va_start(args,nargs);
  189. purpose = va_arg(args, Lisp_Object);
  190. buf = va_arg(args, Lisp_Object);
  191. buf_length = va_arg(args, Lisp_Object);
  192. va_end(args);
  193. if (!(is_vector(buf) && type_of_header(vechdr(buf)) == TYPE_STRING) )
  194. return aerror("sock_send_string_len");
  195. else
  196. return onevalue(fixnum_of_int(
  197. sock_send_string_len(ccl2int(purpose,"sock_send_string_len"),
  198. &celt(buf,0),
  199. ccl2int(buf_length,"sock_send_string_len") )));
  200. }
  201. Lisp_Object LsockGetFloat(Lisp_Object nil, Lisp_Object purpose)
  202. {
  203. return onevalue(make_boxfloat(sock_get_float(
  204. ccl2int(purpose,"sock_get_float")), TYPE_DOUBLE_FLOAT) );
  205. }
  206. Lisp_Object LsockSendFloat(Lisp_Object nil, Lisp_Object purpose, Lisp_Object val)
  207. {
  208. if (!is_number(val)) aerror("sock_send_float");
  209. return onevalue(fixnum_of_int(sock_send_float(
  210. ccl2int(purpose,"sock_send_float"),
  211. float_of_number(val) )));
  212. }
  213. Lisp_Object LsockSendWakeup(Lisp_Object nil, Lisp_Object purpose)
  214. {
  215. return onevalue(fixnum_of_int(sock_send_wakeup(ccl2int(purpose,
  216. "sock_send_wakeup"))));
  217. }
  218. Lisp_Object MS_CDECL LserverSwitch(Lisp_Object nil, int nargs, ...)
  219. {
  220. argcheck(nargs, 0, "server_switch");
  221. return onevalue(fixnum_of_int(server_switch()));
  222. }
  223. Lisp_Object MS_CDECL LflushStdout(Lisp_Object nil, int nargs, ...)
  224. {
  225. argcheck(nargs, 0, "flush_stdout");
  226. return onevalue(fixnum_of_int(flush_stdout()));
  227. }
  228. Lisp_Object LsockSendSignal(Lisp_Object nil,Lisp_Object purpose,Lisp_Object sig)
  229. {
  230. return onevalue(fixnum_of_int(sock_send_signal(
  231. ccl2int(purpose,"sock_send_signal"),
  232. ccl2int(sig,"sock_send_signal"))));
  233. }
  234. Lisp_Object LprintLine(Lisp_Object nil, Lisp_Object buf)
  235. {
  236. if (!(is_vector(buf) && type_of_header(vechdr(buf)) == TYPE_STRING) )
  237. return aerror("print_line");
  238. else
  239. return onevalue(fixnum_of_int(print_line(&celt(buf,0))));
  240. }
  241. #endif /* UNIX */
  242. #if defined(__i386__) || defined(__i486__)|| defined(__i386)||defined(__i586)
  243. static unsigned char plus_infinity[8]= {0x0,0x0,0x0,0x0,0x0,0x0,0xf0,0x7f},
  244. minus_infinity[8]={0x0,0x0,0x0,0x0,0x0,0x0,0xf0,0xff},
  245. NANQ[8]= {0x0,0x0,0x0,0x0,0x0,0x0,0xf8,0xff};
  246. #elif defined(__alpha)
  247. static unsigned char plus_infinity[8]= {0x0,0x0,0x0,0x0,0x0,0x0,0xf0,0x7f},
  248. minus_infinity[8]={0x0,0x0,0x0,0x0,0x0,0x0,0xf0,0xff},
  249. NANQ[8]= {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x7f};
  250. #else
  251. static unsigned char plus_infinity[8]= {0x7f,0xf0,0x0,0x0,0x0,0x0,0x0,0x0},
  252. minus_infinity[8]={0xff,0xf0,0x0,0x0,0x0,0x0,0x0,0x0},
  253. NANQ[8]= {0x7f,0xff,0xff,0xff,0xff,0xff,0xff,0xff};
  254. #endif
  255. Lisp_Object MS_CDECL LplusInfinity(Lisp_Object nil, int nargs, ...)
  256. {
  257. argcheck(nargs, 0, "plus_infinity");
  258. return onevalue(make_boxfloat(*(double *)plus_infinity,TYPE_DOUBLE_FLOAT));
  259. }
  260. Lisp_Object MS_CDECL LminusInfinity(Lisp_Object nil, int nargs, ...)
  261. {
  262. argcheck(nargs, 0, "minus_infinity");
  263. return onevalue(make_boxfloat(*(double *)minus_infinity,TYPE_DOUBLE_FLOAT));
  264. }
  265. Lisp_Object MS_CDECL Lnanq(Lisp_Object nil, int nargs, ...)
  266. {
  267. argcheck(nargs, 0, "NANQ");
  268. return onevalue(make_boxfloat(*(double *)NANQ,TYPE_DOUBLE_FLOAT));
  269. }
  270. Lisp_Object sock_error1(Lisp_Object nil, Lisp_Object arg)
  271. {
  272. return aerror0("Attempt to call socket function on non-unix platform");
  273. }
  274. Lisp_Object sock_error2(Lisp_Object nil, Lisp_Object arg1, Lisp_Object arg2)
  275. {
  276. return aerror0("Attempt to call socket function on non-unix platform");
  277. }
  278. Lisp_Object MS_CDECL sock_error0(Lisp_Object nil, int nargs, ...)
  279. {
  280. return aerror0("Attempt to call socket function on non-unix platform");
  281. }
  282. setup_type const socket_setup[] =
  283. {
  284. #ifdef FLEX
  285. {"init-lm", Linit_lm, too_many_1, wrong_no_1},
  286. {"close-lm", wrong_no_0a, wrong_no_0b, Lclose_lm},
  287. #else
  288. {"init-lm", Linit_lm, too_many_1, wrong_no_1},
  289. {"close-lm", sock_error1, sock_error2, sock_error0},
  290. #endif
  291. #ifdef RealSockets
  292. {"open_server", LopenServer, too_many_1, wrong_no_1},
  293. {"sock_get_int", LsockGetInt, too_many_1, wrong_no_1},
  294. {"sock_send_int", too_few_2, LsockSendInt, wrong_no_2},
  295. {"sock_get_string_buf", wrong_no_na, wrong_no_nb, LsockGetStringBuf},
  296. {"sock_send_string_len", wrong_no_na, wrong_no_nb, LsockSendStringLen},
  297. {"sock_get_float", LsockGetFloat, too_many_1, wrong_no_1},
  298. {"sock_send_float", too_few_2, LsockSendFloat, wrong_no_2},
  299. {"sock_send_wakeup", LsockSendWakeup, too_many_1, wrong_no_1},
  300. {"server_switch", wrong_no_0a, wrong_no_0b, LserverSwitch},
  301. {"flush_stdout", wrong_no_0a, wrong_no_0b, LflushStdout},
  302. {"sock_send_signal", too_few_2, LsockSendSignal, wrong_no_2},
  303. {"print_line", LprintLine, too_many_1, wrong_no_1},
  304. #else
  305. {"open_server", sock_error1, sock_error2, sock_error0},
  306. {"sock_get_int", sock_error1, sock_error2, sock_error0},
  307. {"sock_send_int", sock_error1, sock_error2, sock_error0},
  308. {"sock_get_string_buf", sock_error1, sock_error2, sock_error0},
  309. {"sock_send_string_len", sock_error1, sock_error2, sock_error0},
  310. {"sock_get_float", sock_error1, sock_error2, sock_error0},
  311. {"sock_send_float", sock_error1, sock_error2, sock_error0},
  312. {"sock_send_wakeup", sock_error1, sock_error2, sock_error0},
  313. {"server_switch", sock_error1, sock_error2, sock_error0},
  314. {"flush_stdout", sock_error1, sock_error2, sock_error0},
  315. {"sock_send_signal", sock_error1, sock_error2, sock_error0},
  316. {"print_line", sock_error1, sock_error2, sock_error0},
  317. #endif
  318. {"plus_infinity", wrong_no_0a, wrong_no_0b, LplusInfinity},
  319. {"minus_infinity", wrong_no_0a, wrong_no_0b, LminusInfinity},
  320. {"NANQ", wrong_no_0a, wrong_no_0b, Lnanq},
  321. {NULL, 0, 0, 0}
  322. };