~ubuntu-branches/debian/lenny/netatalk/lenny

« back to all changes in this revision

Viewing changes to libatalk/dsi/dsi_tcp.c

  • Committer: Bazaar Package Importer
  • Author(s): Ante Karamatic
  • Date: 2005-10-07 13:46:11 UTC
  • mfrom: (1.1.2 upstream) (2.1.1 sarge)
  • Revision ID: james.westby@ubuntu.com-20051007134611-r07qa2g67xwkp2if
Tags: 2.0.3-1ubuntu1
* debian/netatalk.init
  - run cnid_metad if CNID_METAD_RUN=yes

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/*
2
 
 * $Id: dsi_tcp.c,v 1.9.4.2 2003/11/14 14:25:41 didg Exp $
 
2
 * $Id: dsi_tcp.c,v 1.9.10.7.2.1 2005/01/11 23:00:42 didg Exp $
3
3
 *
4
4
 * Copyright (c) 1997, 1998 Adrian Sun (asun@zoology.washington.edu)
5
5
 * All rights reserved. See COPYRIGHT.
90
90
static void timeout_handler()
91
91
{
92
92
  LOG(log_error, logtype_default, "dsi_tcp_open: connection timed out");
93
 
  exit(1);
 
93
  exit(EXITERR_CLNT);
94
94
}
95
95
 
 
96
#ifdef ATACC
 
97
#define fork aTaC_fork
 
98
#endif
 
99
 
 
100
static struct itimerval itimer;
96
101
/* accept the socket and do a little sanity checking */
97
102
static int dsi_tcp_open(DSI *dsi)
98
103
{
120
125
  if (dsi->socket < 0)
121
126
    return -1;
122
127
 
123
 
  if ((pid = fork()) == 0) { /* child */
124
 
    static const struct itimerval timer = {{0, 0}, {DSI_TCPTIMEOUT, 0}};
 
128
  getitimer(ITIMER_PROF, &itimer);
 
129
  if (0 == (pid = fork()) ) { /* child */
 
130
    static struct itimerval timer = {{0, 0}, {DSI_TCPTIMEOUT, 0}};
125
131
    struct sigaction newact, oldact;
126
132
    u_int8_t block[DSI_BLOCKSIZ];
127
133
    size_t stored;
135
141
    newact.sa_flags = 0;
136
142
    sigemptyset(&oldact.sa_mask);
137
143
    oldact.sa_flags = 0;
 
144
    setitimer(ITIMER_PROF, &itimer, NULL);
 
145
 
138
146
    if ((sigaction(SIGALRM, &newact, &oldact) < 0) ||
139
147
        (setitimer(ITIMER_REAL, &timer, NULL) < 0)) {
140
148
        LOG(log_error, logtype_default, "dsi_tcp_open: %s", strerror(errno));
141
 
        exit(1);
 
149
        exit(EXITERR_SYS);
142
150
    }
143
151
    
144
152
    /* read in commands. this is similar to dsi_receive except
149
157
    len = dsi_stream_read(dsi, block, 2);
150
158
    if (!len ) {
151
159
      /* connection already closed, don't log it (normal OSX 10.3 behaviour) */
152
 
      exit(1);
 
160
      exit(EXITERR_CLNT);
153
161
    }
154
 
 
155
162
    if (len < 2 || (block[0] > DSIFL_MAX) || (block[1] > DSIFUNC_MAX)) {
156
163
      LOG(log_error, logtype_default, "dsi_tcp_open: invalid header");
157
 
      exit(1);
 
164
      exit(EXITERR_CLNT);
158
165
    }      
159
166
    
160
167
    /* read in the rest of the header */
165
172
        stored += len;
166
173
      else {
167
174
        LOG(log_error, logtype_default, "dsi_tcp_open: stream_read: %s", strerror(errno));
168
 
        exit(1);
 
175
        exit(EXITERR_CLNT);
169
176
      }
170
177
    }
171
178
    
189
196
        stored += len;
190
197
      else {
191
198
        LOG(log_error, logtype_default, "dsi_tcp_open: stream_read: %s", strerror(errno));
192
 
        exit(1);
 
199
        exit(EXITERR_CLNT);
193
200
      }
194
201
    }
195
202
    
196
 
    /* restore signal */
 
203
    /* stop timer and restore signal handler */
 
204
    memset(&timer, 0, sizeof(timer));
 
205
    setitimer(ITIMER_REAL, &timer, NULL);
197
206
    sigaction(SIGALRM, &oldact, NULL);
198
207
 
199
208
    LOG(log_info, logtype_default,"ASIP session:%u(%d) from %s:%u(%d)", 
246
255
#ifdef SO_REUSEADDR
247
256
    port = 1;
248
257
    setsockopt(dsi->serversock, SOL_SOCKET, SO_REUSEADDR, &port, sizeof(port));
249
 
#endif /* SO_REUSEADDR */
 
258
#endif
250
259
 
251
260
#ifdef USE_TCP_NODELAY 
 
261
 
252
262
#ifndef SOL_TCP
253
263
#define SOL_TCP IPPROTO_TCP
254
 
#endif /* ! SOL_TCP */
 
264
#endif 
 
265
 
255
266
    port = 1;
256
267
    setsockopt(dsi->serversock, SOL_TCP, TCP_NODELAY, &port, sizeof(port));
257
268
#endif /* USE_TCP_NODELAY */
265
276
    }
266
277
  }
267
278
 
 
279
  /* Point protocol specific functions to tcp versions */
 
280
  dsi->proto_open = dsi_tcp_open;
 
281
  dsi->proto_close = dsi_tcp_close;
 
282
 
268
283
  /* get real address for GetStatus. we'll go through the list of 
269
284
   * interfaces if necessary. */
270
 
  if (!address) {
271
 
    if ((host = gethostbyname(hostname))) /* we can resolve the name */
272
 
      dsi->server.sin_addr.s_addr = ((struct in_addr *) host->h_addr)->s_addr;
273
 
    else {
 
285
 
 
286
  if (address) {
 
287
      /* address is a parameter, use it 'as is' */
 
288
      return 1;
 
289
  }
 
290
  
 
291
  if (!(host = gethostbyname(hostname)) ) { /* we can't resolve the name */
 
292
 
 
293
      LOG(log_info, logtype_default, "dsi_tcp: cannot resolve hostname '%s'", hostname);
 
294
      if (proxy) {
 
295
         /* give up we have nothing to advertise */
 
296
         return 0;
 
297
      }
 
298
  }
 
299
  else {
 
300
      if (((struct in_addr *) host->h_addr)->s_addr != 0x100007F) { /* FIXME ugly check */
 
301
          dsi->server.sin_addr.s_addr = ((struct in_addr *) host->h_addr)->s_addr;
 
302
          return 1;
 
303
      }
 
304
      LOG(log_info, logtype_default, "dsi_tcp: hostname '%s' resolves to loopback address", hostname);
 
305
  }
 
306
  {
274
307
      char **start, **list;
275
308
      struct ifreq ifr;
276
309
 
277
310
      /* get it from the interface list */
278
311
      start = list = getifacelist();
279
312
      while (list && *list) {
280
 
        strncpy(ifr.ifr_name, *list, sizeof(ifr.ifr_name));
281
 
        list++;
 
313
          strlcpy(ifr.ifr_name, *list, sizeof(ifr.ifr_name));
 
314
          list++;
282
315
 
283
316
#ifndef IFF_SLAVE
284
317
#define IFF_SLAVE 0
285
 
#endif /* ! IFF_SLAVE */
286
 
        if (ioctl(dsi->serversock, SIOCGIFFLAGS, &ifr) < 0)
287
 
          continue;
288
 
 
289
 
        if (ifr.ifr_flags & (IFF_LOOPBACK | IFF_POINTOPOINT | IFF_SLAVE))
290
 
          continue;
291
 
 
292
 
        if ((ifr.ifr_flags & IFF_UP) == 0)
293
 
          continue;
294
 
 
295
 
        if (ioctl(dsi->serversock, SIOCGIFADDR, &ifr) < 0)
296
 
          continue;
 
318
#endif
 
319
 
 
320
          if (ioctl(dsi->serversock, SIOCGIFFLAGS, &ifr) < 0)
 
321
            continue;
 
322
 
 
323
          if (ifr.ifr_flags & (IFF_LOOPBACK | IFF_POINTOPOINT | IFF_SLAVE))
 
324
            continue;
 
325
 
 
326
          if (!(ifr.ifr_flags & (IFF_UP | IFF_RUNNING)) )
 
327
            continue;
 
328
 
 
329
          if (ioctl(dsi->serversock, SIOCGIFADDR, &ifr) < 0)
 
330
            continue;
297
331
        
298
 
        dsi->server.sin_addr.s_addr = 
299
 
          ((struct sockaddr_in *) &ifr.ifr_addr)->sin_addr.s_addr;
300
 
        LOG(log_info, logtype_default, "dsi_tcp: Can't resolve hostname (%s).\n"
301
 
               "%s on interface %s will be used instead.", hostname,
 
332
          dsi->server.sin_addr.s_addr = 
 
333
            ((struct sockaddr_in *) &ifr.ifr_addr)->sin_addr.s_addr;
 
334
          LOG(log_info, logtype_default, "dsi_tcp: '%s' on interface '%s' will be used instead.",
302
335
               inet_ntoa(dsi->server.sin_addr), ifr.ifr_name);
303
 
        goto iflist_done;
304
 
 
 
336
          goto iflist_done;
305
337
      }
306
 
      LOG(log_info, logtype_default, "dsi_tcp (Chooser will not select afp/tcp)\n\
307
 
Check to make sure %s is in /etc/hosts and the correct domain is in\n\
 
338
      LOG(log_info, logtype_default, "dsi_tcp (Chooser will not select afp/tcp) \
 
339
Check to make sure %s is in /etc/hosts and the correct domain is in \
308
340
/etc/resolv.conf: %s", hostname, strerror(errno));
309
341
 
310
342
iflist_done:
311
343
      if (start)
312
 
        freeifacelist(start);
313
 
    }
 
344
          freeifacelist(start);
314
345
  }
315
346
 
316
 
  /* everything's set up. now point protocol specific functions to 
317
 
   * tcp versions */
318
 
  dsi->proto_open = dsi_tcp_open;
319
 
  dsi->proto_close = dsi_tcp_close;
320
347
  return 1;
321
348
 
322
349
}