client.c 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112
  1. #include <stdio.h>
  2. #include <signal.h>
  3. #include <string.h>
  4. #include <fcntl.h>
  5. #include <sys/time.h>
  6. #include <sys/socket.h>
  7. #include <netinet/in.h>
  8. #include <linux/kd.h>
  9. #define CLK_FREQ 1193180
  10. int term;
  11. static int ident = 0x42454550;
  12. enum cmd_t {CMD_KA, CMD_PING, CMD_QUIT, CMD_PLAY, CMD_CAPS};
  13. struct cmd_buffer {
  14. int cmd;
  15. union {
  16. int data[8];
  17. char string[8*sizeof(int)];
  18. };
  19. };
  20. void sigalrm(int sig) {
  21. ioctl(term, KIOCSOUND, 0);
  22. }
  23. int main(int argc, char **argv) {
  24. struct sockaddr_in addr, remote;
  25. int sock, rlen = sizeof(remote), i, len_uid = 0;
  26. struct itimerval tmr;
  27. struct cmd_buffer cmd;
  28. struct sigaction sa;
  29. if(argc > 1) {
  30. len_uid = strlen(argv[1]);
  31. }
  32. if((term = open("/dev/console", O_WRONLY)) < 0) {
  33. perror("open");
  34. return 1;
  35. }
  36. if((sock = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
  37. perror("socket");
  38. return 1;
  39. }
  40. memset(&addr, 0, sizeof(addr));
  41. addr.sin_family = AF_INET;
  42. addr.sin_addr.s_addr = htonl(INADDR_ANY);
  43. addr.sin_port = htons(13676);
  44. if((bind(sock, (struct sockaddr *) &addr, sizeof(addr))) < 0) {
  45. perror("bind");
  46. return 1;
  47. }
  48. sa.sa_handler = sigalrm;
  49. sa.sa_flags = SA_NODEFER | SA_RESTART;
  50. sigemptyset(&sa.sa_mask);
  51. sigaction(SIGALRM, &sa, NULL);
  52. printf("Ready to begin (listening on 13676)\n");
  53. memset(&tmr, 0, sizeof(tmr));
  54. while(1) {
  55. if(recvfrom(sock, &cmd, sizeof(cmd), 0, (struct sockaddr *) &remote, &rlen) < 0) {
  56. perror("recvfrom");
  57. return 1;
  58. }
  59. cmd.cmd = ntohl(cmd.cmd);
  60. for(i = 0; i < 8; i++) cmd.data[i] = ntohl(cmd.data[i]);
  61. /* printf("From %s:%d, cmd %d\n", inet_ntoa(remote.sin_addr.s_addr), remote.sin_port, cmd.cmd); */
  62. switch((enum cmd_t) cmd.cmd) {
  63. case CMD_QUIT:
  64. return 0;
  65. break;
  66. case CMD_PING:
  67. sendto(sock, &cmd, sizeof(cmd), 0, (struct sockaddr *) &remote, rlen);
  68. break;
  69. case CMD_PLAY:
  70. tmr.it_value.tv_sec = cmd.data[0];
  71. tmr.it_value.tv_usec = cmd.data[1];
  72. setitimer(ITIMER_REAL, &tmr, NULL);
  73. ioctl(term, KIOCSOUND, (int) (CLK_FREQ / cmd.data[2]));
  74. break;
  75. case CMD_CAPS:
  76. cmd.cmd = htonl(cmd.cmd);
  77. cmd.data[0] = htonl(1);
  78. cmd.data[1] = htonl(ident);
  79. for(i = 0; i < 6 * sizeof(int); i++) {
  80. if(argc > 1 && i < len_uid) {
  81. cmd.string[i+8] = argv[1][i];
  82. } else {
  83. cmd.string[i+8] = '\0';
  84. }
  85. }
  86. sendto(sock, &cmd, sizeof(cmd), 0, (struct sockaddr *) &remote, rlen);
  87. break;
  88. default:
  89. printf("WARNING: Unknown cmd %d\n", cmd.cmd);
  90. case CMD_KA:
  91. break;
  92. }
  93. }
  94. }