- if (dsi->socket < 0)
- return -1;
-
- getitimer(ITIMER_PROF, &itimer);
- if (0 == (pid = fork()) ) { /* child */
- static struct itimerval timer = {{0, 0}, {DSI_TCPTIMEOUT, 0}};
- struct sigaction newact, oldact;
- u_int8_t block[DSI_BLOCKSIZ];
- size_t stored;
-
- /* reset signals */
- server_reset_signal();
-
- /* install an alarm to deal with non-responsive connections */
- newact.sa_handler = timeout_handler;
- sigemptyset(&newact.sa_mask);
- newact.sa_flags = 0;
- sigemptyset(&oldact.sa_mask);
- oldact.sa_flags = 0;
- setitimer(ITIMER_PROF, &itimer, NULL);
-
- if ((sigaction(SIGALRM, &newact, &oldact) < 0) ||
- (setitimer(ITIMER_REAL, &timer, NULL) < 0)) {
- LOG(log_error, logtype_default, "dsi_tcp_open: %s", strerror(errno));
- exit(EXITERR_SYS);
- }
-
- /* read in commands. this is similar to dsi_receive except
- * for the fact that we do some sanity checking to prevent
- * delinquent connections from causing mischief. */
-
- /* read in the first two bytes */
- len = dsi_stream_read(dsi, block, 2);
- if (!len ) {
- /* connection already closed, don't log it (normal OSX 10.3 behaviour) */
- exit(EXITERR_CLNT);
- }
- if (len < 2 || (block[0] > DSIFL_MAX) || (block[1] > DSIFUNC_MAX)) {
- LOG(log_error, logtype_default, "dsi_tcp_open: invalid header");
- exit(EXITERR_CLNT);
- }
-
- /* read in the rest of the header */
- stored = 2;
- while (stored < DSI_BLOCKSIZ) {
- len = dsi_stream_read(dsi, block + stored, sizeof(block) - stored);
- if (len > 0)
- stored += len;
- else {
- LOG(log_error, logtype_default, "dsi_tcp_open: stream_read: %s", strerror(errno));
- exit(EXITERR_CLNT);
- }
+ if (dsi->socket < 0)
+ return -1;
+
+ getitimer(ITIMER_PROF, &itimer);
+ if (0 == (pid = fork()) ) { /* child */
+ static struct itimerval timer = {{0, 0}, {DSI_TCPTIMEOUT, 0}};
+ struct sigaction newact, oldact;
+ uint8_t block[DSI_BLOCKSIZ];
+ size_t stored;
+
+ /* Immediateyl mark globally that we're a child now */
+ parent_or_child = 1;
+
+ /* reset signals */
+ server_reset_signal();
+
+#ifndef DEBUGGING
+ /* install an alarm to deal with non-responsive connections */
+ newact.sa_handler = timeout_handler;
+ sigemptyset(&newact.sa_mask);
+ newact.sa_flags = 0;
+ sigemptyset(&oldact.sa_mask);
+ oldact.sa_flags = 0;
+ setitimer(ITIMER_PROF, &itimer, NULL);
+
+ if ((sigaction(SIGALRM, &newact, &oldact) < 0) ||
+ (setitimer(ITIMER_REAL, &timer, NULL) < 0)) {
+ LOG(log_error, logtype_dsi, "dsi_tcp_open: %s", strerror(errno));
+ exit(EXITERR_SYS);
+ }
+#endif
+
+ /* read in commands. this is similar to dsi_receive except
+ * for the fact that we do some sanity checking to prevent
+ * delinquent connections from causing mischief. */
+
+ /* read in the first two bytes */
+ len = dsi_stream_read(dsi, block, 2);
+ if (!len ) {
+ /* connection already closed, don't log it (normal OSX 10.3 behaviour) */
+ exit(EXITERR_CLNT);
+ }
+ if (len < 2 || (block[0] > DSIFL_MAX) || (block[1] > DSIFUNC_MAX)) {
+ LOG(log_error, logtype_dsi, "dsi_tcp_open: invalid header");
+ exit(EXITERR_CLNT);
+ }
+
+ /* read in the rest of the header */
+ stored = 2;
+ while (stored < DSI_BLOCKSIZ) {
+ len = dsi_stream_read(dsi, block + stored, sizeof(block) - stored);
+ if (len > 0)
+ stored += len;
+ else {
+ LOG(log_error, logtype_dsi, "dsi_tcp_open: stream_read: %s", strerror(errno));
+ exit(EXITERR_CLNT);
+ }
+ }
+
+ dsi->header.dsi_flags = block[0];
+ dsi->header.dsi_command = block[1];
+ memcpy(&dsi->header.dsi_requestID, block + 2,
+ sizeof(dsi->header.dsi_requestID));
+ memcpy(&dsi->header.dsi_code, block + 4, sizeof(dsi->header.dsi_code));
+ memcpy(&dsi->header.dsi_len, block + 8, sizeof(dsi->header.dsi_len));
+ memcpy(&dsi->header.dsi_reserved, block + 12,
+ sizeof(dsi->header.dsi_reserved));
+ dsi->clientID = ntohs(dsi->header.dsi_requestID);
+
+ /* make sure we don't over-write our buffers. */
+ dsi->cmdlen = min(ntohl(dsi->header.dsi_len), DSI_CMDSIZ);
+
+ stored = 0;
+ while (stored < dsi->cmdlen) {
+ len = dsi_stream_read(dsi, dsi->commands + stored, dsi->cmdlen - stored);
+ if (len > 0)
+ stored += len;
+ else {
+ LOG(log_error, logtype_dsi, "dsi_tcp_open: stream_read: %s", strerror(errno));
+ exit(EXITERR_CLNT);
+ }
+ }
+
+ /* stop timer and restore signal handler */
+#ifndef DEBUGGING
+ memset(&timer, 0, sizeof(timer));
+ setitimer(ITIMER_REAL, &timer, NULL);
+ sigaction(SIGALRM, &oldact, NULL);
+#endif
+
+ LOG(log_info, logtype_dsi, "AFP/TCP session from %s:%u",
+ getip_string((struct sockaddr *)&dsi->client),
+ getip_port((struct sockaddr *)&dsi->client));