utils.c 4.28 KB
Newer Older
1 2 3 4 5
#include "utils.h"
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <time.h>
Cedric Roux's avatar
Cedric Roux committed
6
#include <unistd.h>
7
#include <ctype.h>
8 9
#include <netinet/in.h>
#include <arpa/inet.h>
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

void new_thread(void *(*f)(void *), void *data)
{
  pthread_t t;
  pthread_attr_t att;

  if (pthread_attr_init(&att))
    { fprintf(stderr, "pthread_attr_init err\n"); exit(1); }
  if (pthread_attr_setdetachstate(&att, PTHREAD_CREATE_DETACHED))
    { fprintf(stderr, "pthread_attr_setdetachstate err\n"); exit(1); }
  if (pthread_attr_setstacksize(&att, 10000000))
    { fprintf(stderr, "pthread_attr_setstacksize err\n"); exit(1); }
  if (pthread_create(&t, &att, f, data))
    { fprintf(stderr, "pthread_create err\n"); exit(1); }
  if (pthread_attr_destroy(&att))
    { fprintf(stderr, "pthread_attr_destroy err\n"); exit(1); }
}

void sleepms(int ms)
{
  struct timespec t;

  t.tv_sec = ms / 1000;
  t.tv_nsec = (ms % 1000) * 1000000L;

  /* TODO: deal with EINTR */
  if (nanosleep(&t, NULL)) abort();
}

/****************************************************************************/
/* list                                                                     */
/****************************************************************************/

list *list_remove_head(list *l)
{
  list *ret;
  if (l == NULL) return NULL;
  ret = l->next;
  if (ret != NULL) ret->last = l->last;
  free(l);
  return ret;
}

list *list_append(list *l, void *data)
{
  list *new = calloc(1, sizeof(list));
  if (new == NULL) abort();
  new->data = data;
  if (l == NULL) {
    new->last = new;
    return new;
  }
  l->last->next = new;
  l->last = new;
  return l;
}
Cedric Roux's avatar
Cedric Roux committed
66 67 68 69 70

/****************************************************************************/
/* socket                                                                   */
/****************************************************************************/

71
int socket_send(int socket, void *buffer, int size)
Cedric Roux's avatar
Cedric Roux committed
72 73 74 75 76
{
  char *x = buffer;
  int ret;
  while (size) {
    ret = write(socket, x, size);
77
    if (ret <= 0) return -1;
Cedric Roux's avatar
Cedric Roux committed
78 79 80
    size -= ret;
    x += ret;
  }
81
  return 0;
Cedric Roux's avatar
Cedric Roux committed
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
int get_connection(char *addr, int port)
{
  struct sockaddr_in a;
  socklen_t alen;
  int s, t;

  printf("waiting for connection on %s:%d\n", addr, port);

  s = socket(AF_INET, SOCK_STREAM, 0);
  if (s == -1) { perror("socket"); exit(1); }
  t = 1;
  if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &t, sizeof(int)))
    { perror("setsockopt"); exit(1); }

  a.sin_family = AF_INET;
  a.sin_port = htons(port);
  a.sin_addr.s_addr = inet_addr(addr);

  if (bind(s, (struct sockaddr *)&a, sizeof(a))) { perror("bind"); exit(1); }
  if (listen(s, 5)) { perror("bind"); exit(1); }
  alen = sizeof(a);
  t = accept(s, (struct sockaddr *)&a, &alen);
  if (t == -1) { perror("accept"); exit(1); }
  close(s);

  printf("connected\n");

  return t;
}

int fullread(int fd, void *_buf, int count)
{
  char *buf = _buf;
  int ret = 0;
  int l;
  while (count) {
    l = read(fd, buf, count);
121
    if (l <= 0) return -1;
122 123 124 125 126 127 128
    count -= l;
    buf += l;
    ret += l;
  }
  return ret;
}

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
int connect_to(char *addr, int port)
{
  int s;
  struct sockaddr_in a;

  printf("connecting to %s:%d\n", addr, port);

again:
  s = socket(AF_INET, SOCK_STREAM, 0);
  if (s == -1) { perror("socket"); exit(1); }

  a.sin_family = AF_INET;
  a.sin_port = htons(port);
  a.sin_addr.s_addr = inet_addr(addr);

  if (connect(s, (struct sockaddr *)&a, sizeof(a)) == -1) {
    perror("connect");
    close(s);
    printf("trying again in 1s\n");
    sleep(1);
    goto again;
  }

  return s;
}

Cedric Roux's avatar
Cedric Roux committed
155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174
/****************************************************************************/
/* buffer                                                                   */
/****************************************************************************/

void PUTC(OBUF *o, char c)
{
  if (o->osize == o->omaxsize) {
    o->omaxsize += 512;
    o->obuf = realloc(o->obuf, o->omaxsize);
    if (o->obuf == NULL) abort();
  }
  o->obuf[o->osize] = c;
  o->osize++;
}

void PUTS(OBUF *o, char *s)
{
  while (*s) PUTC(o, *s++);
}

175 176 177 178 179 180 181 182 183 184 185
static int clean(char c)
{
  if (!isprint(c)) c = ' ';
  return c;
}

void PUTS_CLEAN(OBUF *o, char *s)
{
  while (*s) PUTC(o, clean(*s++));
}

Cedric Roux's avatar
Cedric Roux committed
186 187 188 189 190 191
void PUTI(OBUF *o, int i)
{
  char s[64];
  sprintf(s, "%d", i);
  PUTS(o, s);
}
Cedric Roux's avatar
Cedric Roux committed
192 193 194 195 196 197 198

void PUTUL(OBUF *o, unsigned long l)
{
  char s[128];
  sprintf(s, "%ld", l);
  PUTS(o, s);
}