/target-src/dcload/syscalls.c

https://github.com/thentenaar/dc-load-ip · C · 365 lines · 239 code · 97 blank · 29 comment · 4 complexity · 79129d1171eb812ae083d05d6ac81709 MD5 · raw file

  1. /*
  2. * This file is part of the dcload Dreamcast ethernet loader
  3. *
  4. * Copyright (C) 2001 Andrew Kieschnick <andrewk@austin.rr.com>
  5. *
  6. * This program is free software; you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License as published by
  8. * the Free Software Foundation; either version 2 of the License, or
  9. * (at your option) any later version.
  10. *
  11. * This program is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU General Public License
  17. * along with this program; if not, write to the Free Software
  18. * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  19. *
  20. */
  21. #include <unistd.h>
  22. #include <sys/types.h>
  23. #include <sys/stat.h>
  24. #include <fcntl.h>
  25. #include <utime.h>
  26. #include <stdarg.h>
  27. #include <dirent.h>
  28. #include "syscalls.h"
  29. #include "packet.h"
  30. #include "net.h"
  31. #include "rtl8139.h"
  32. #include "commands.h"
  33. #include "scif.h"
  34. unsigned int syscall_retval;
  35. ether_header_t * ether = (ether_header_t *)pkt_buf;
  36. ip_header_t * ip = (ip_header_t *)(pkt_buf + ETHER_H_LEN);
  37. udp_header_t * udp = (udp_header_t *)(pkt_buf + ETHER_H_LEN + IP_H_LEN);
  38. /* send command, enable bb, bb_loop(), then return */
  39. int strlen(const char *s)
  40. {
  41. int c = 0;
  42. while (s[c] != 0)
  43. c++;
  44. return c;
  45. }
  46. void build_send_packet(int command_len)
  47. {
  48. unsigned char * command = pkt_buf + ETHER_H_LEN + IP_H_LEN + UDP_H_LEN;
  49. /*
  50. scif_puts("build_send_packet\n");
  51. scif_putchar(command[0]);
  52. scif_putchar(command[1]);
  53. scif_putchar(command[2]);
  54. scif_putchar(command[3]);
  55. scif_puts("\n");
  56. */
  57. make_ether(tool_mac, rtl.mac, ether);
  58. make_ip(tool_ip, our_ip, UDP_H_LEN + command_len, 17, ip);
  59. make_udp(tool_port, 31313, command, command_len, ip, udp);
  60. bb_start();
  61. bb_tx(pkt_buf, ETHER_H_LEN + IP_H_LEN + UDP_H_LEN + command_len);
  62. }
  63. void dcexit(void)
  64. {
  65. command_t * command = (command_t *)(pkt_buf + ETHER_H_LEN + IP_H_LEN + UDP_H_LEN);
  66. memcpy(command->id, CMD_EXIT, 4);
  67. command->address = htonl(0);
  68. command->size = htonl(0);
  69. build_send_packet(COMMAND_LEN);
  70. bb_stop();
  71. }
  72. int read(int fd, void *buf, size_t count)
  73. {
  74. command_3int_t * command = (command_3int_t *)(pkt_buf + ETHER_H_LEN + IP_H_LEN + UDP_H_LEN);
  75. memcpy(command->id, CMD_READ, 4);
  76. command->value0 = htonl(fd);
  77. command->value1 = htonl(buf);
  78. command->value2 = htonl(count);
  79. build_send_packet(sizeof(command_3int_t));
  80. bb_loop();
  81. return syscall_retval;
  82. }
  83. int write(int fd, const void *buf, size_t count)
  84. {
  85. command_3int_t * command = (command_3int_t *)(pkt_buf + ETHER_H_LEN + IP_H_LEN + UDP_H_LEN);
  86. memcpy(command->id, CMD_WRITE, 4);
  87. command->value0 = htonl(fd);
  88. command->value1 = htonl(buf);
  89. command->value2 = htonl(count);
  90. build_send_packet(sizeof(command_3int_t));
  91. bb_loop();
  92. return syscall_retval;
  93. }
  94. int open(const char *pathname, int flags, ...)
  95. {
  96. va_list ap;
  97. command_2int_string_t * command = (command_2int_string_t *)(pkt_buf + ETHER_H_LEN + IP_H_LEN + UDP_H_LEN);
  98. int namelen = strlen(pathname);
  99. memcpy(command->id, CMD_OPEN, 4);
  100. va_start(ap, flags);
  101. command->value0 = htonl(flags);
  102. command->value1 = htonl(va_arg(ap, int));
  103. va_end(ap);
  104. memcpy(command->string, pathname, namelen+1);
  105. build_send_packet(sizeof(command_2int_string_t)+namelen);
  106. bb_loop();
  107. return syscall_retval;
  108. }
  109. int close(int fd)
  110. {
  111. command_int_t * command = (command_int_t *)(pkt_buf + ETHER_H_LEN + IP_H_LEN + UDP_H_LEN);
  112. memcpy(command->id, CMD_CLOSE, 4);
  113. command->value0 = htonl(fd);
  114. build_send_packet(sizeof(command_int_t));
  115. bb_loop();
  116. return syscall_retval;
  117. }
  118. int creat(const char *pathname, mode_t mode)
  119. {
  120. command_int_string_t * command = (command_int_string_t *)(pkt_buf + ETHER_H_LEN + IP_H_LEN + UDP_H_LEN);
  121. int namelen = strlen(pathname);
  122. memcpy(command->id, CMD_CREAT, 4);
  123. command->value0 = htonl(mode);
  124. memcpy(command->string, pathname, namelen+1);
  125. build_send_packet(sizeof(command_int_string_t)+namelen);
  126. bb_loop();
  127. return syscall_retval;
  128. }
  129. int link(const char *oldpath, const char *newpath)
  130. {
  131. command_string_t * command = (command_string_t *)(pkt_buf + ETHER_H_LEN + IP_H_LEN + UDP_H_LEN);
  132. int namelen1 = strlen(oldpath);
  133. int namelen2 = strlen(newpath);
  134. memcpy(command->id, CMD_LINK, 4);
  135. memcpy(command->string, oldpath, namelen1 + 1);
  136. memcpy(command->string + namelen1 + 1, newpath, namelen2 + 1);
  137. build_send_packet(sizeof(command_string_t)+namelen1+namelen2+1);
  138. bb_loop();
  139. return syscall_retval;
  140. }
  141. int unlink(const char *pathname)
  142. {
  143. command_string_t * command = (command_string_t *)(pkt_buf + ETHER_H_LEN + IP_H_LEN + UDP_H_LEN);
  144. int namelen = strlen(pathname);
  145. memcpy(command->id, CMD_UNLINK, 4);
  146. memcpy(command->string, pathname, namelen + 1);
  147. build_send_packet(sizeof(command_string_t)+namelen);
  148. bb_loop();
  149. return syscall_retval;
  150. }
  151. int chdir(const char *path)
  152. {
  153. command_string_t * command = (command_string_t *)(pkt_buf + ETHER_H_LEN + IP_H_LEN + UDP_H_LEN);
  154. int namelen = strlen(path);
  155. memcpy(command->id, CMD_CHDIR, 4);
  156. memcpy(command->string, path, namelen + 1);
  157. build_send_packet(sizeof(command_string_t)+namelen);
  158. bb_loop();
  159. return syscall_retval;
  160. }
  161. int chmod(const char *path, mode_t mode)
  162. {
  163. command_int_string_t * command = (command_int_string_t *)(pkt_buf + ETHER_H_LEN + IP_H_LEN + UDP_H_LEN);
  164. int namelen = strlen(path);
  165. memcpy(command->id, CMD_CHMOD, 4);
  166. command->value0 = htonl(mode);
  167. memcpy(command->string, path, namelen+1);
  168. build_send_packet(sizeof(command_int_string_t)+namelen);
  169. bb_loop();
  170. return syscall_retval;
  171. }
  172. off_t lseek(int fildes, off_t offset, int whence)
  173. {
  174. command_3int_t * command = (command_3int_t *)(pkt_buf + ETHER_H_LEN + IP_H_LEN + UDP_H_LEN);
  175. memcpy(command->id, CMD_LSEEK, 4);
  176. command->value0 = htonl(fildes);
  177. command->value1 = htonl(offset);
  178. command->value2 = htonl(whence);
  179. build_send_packet(sizeof(command_3int_t));
  180. bb_loop();
  181. return syscall_retval;
  182. }
  183. int fstat(int filedes, struct stat *buf)
  184. {
  185. command_3int_t * command = (command_3int_t *)(pkt_buf + ETHER_H_LEN + IP_H_LEN + UDP_H_LEN);
  186. memcpy(command->id, CMD_FSTAT, 4);
  187. command->value0 = htonl(filedes);
  188. command->value1 = htonl(buf);
  189. command->value2 = htonl(sizeof(struct stat));
  190. build_send_packet(sizeof(command_3int_t));
  191. bb_loop();
  192. return syscall_retval;
  193. }
  194. time_t time(time_t * t)
  195. {
  196. command_int_t * command = (command_int_t *)(pkt_buf + ETHER_H_LEN + IP_H_LEN + UDP_H_LEN);
  197. memcpy(command->id, CMD_TIME, 4);
  198. build_send_packet(sizeof(command_int_t));
  199. bb_loop();
  200. return syscall_retval;
  201. }
  202. int stat(const char *file_name, struct stat *buf)
  203. {
  204. command_2int_string_t * command = (command_2int_string_t *)(pkt_buf + ETHER_H_LEN + IP_H_LEN + UDP_H_LEN);
  205. int namelen = strlen(file_name);
  206. memcpy(command->id, CMD_STAT, 4);
  207. memcpy(command->string, file_name, namelen+1);
  208. command->value0 = htonl(buf);
  209. command->value1 = htonl(sizeof(struct stat));
  210. build_send_packet(sizeof(command_2int_string_t)+namelen);
  211. bb_loop();
  212. return syscall_retval;
  213. }
  214. int utime(const char *filename, struct utimbuf *buf)
  215. {
  216. command_3int_string_t * command = (command_3int_string_t *)(pkt_buf + ETHER_H_LEN + IP_H_LEN + UDP_H_LEN);
  217. int namelen = strlen(filename);
  218. memcpy(command->id, CMD_UTIME, 4);
  219. memcpy(command->string, filename, namelen+1);
  220. command->value0 = htonl(buf);
  221. if (!buf) {
  222. command->value1 = htonl(buf->actime);
  223. command->value2 = htonl(buf->modtime);
  224. }
  225. build_send_packet(sizeof(command_3int_string_t)+namelen);
  226. bb_loop();
  227. return syscall_retval;
  228. }
  229. DIR * opendir(const char *name)
  230. {
  231. command_string_t * command = (command_string_t *)(pkt_buf + ETHER_H_LEN + IP_H_LEN + UDP_H_LEN);
  232. int namelen = strlen(name);
  233. memcpy(command->id, CMD_OPENDIR, 4);
  234. memcpy(command->string, name, namelen+1);
  235. build_send_packet(sizeof(command_string_t)+namelen);
  236. bb_loop();
  237. return (DIR *)syscall_retval;
  238. }
  239. int closedir(DIR *dir)
  240. {
  241. command_int_t * command = (command_int_t *)(pkt_buf + ETHER_H_LEN + IP_H_LEN + UDP_H_LEN);
  242. memcpy(command->id, CMD_CLOSEDIR, 4);
  243. command->value0 = htonl(dir);
  244. build_send_packet(sizeof(command_int_t));
  245. bb_loop();
  246. return syscall_retval;
  247. }
  248. struct dirent our_dir;
  249. struct dirent *readdir(DIR *dir)
  250. {
  251. command_3int_t * command = (command_3int_t *)(pkt_buf + ETHER_H_LEN + IP_H_LEN + UDP_H_LEN);
  252. memcpy(command->id, CMD_READDIR, 4);
  253. command->value0 = htonl(dir);
  254. command->value1 = htonl(&our_dir);
  255. command->value2 = htonl(sizeof(struct dirent));
  256. build_send_packet(sizeof(command_3int_t));
  257. bb_loop();
  258. if (syscall_retval)
  259. return &our_dir;
  260. else
  261. return 0;
  262. }
  263. int gethostinfo(unsigned int *ip, unsigned int *port)
  264. {
  265. *ip = tool_ip;
  266. *port = tool_port;
  267. return our_ip;
  268. }