+ while (1) {
+ if (sigsetjmp(recon_jmp, 1) != 0)
+ /* returning from SIGALARM handler for a primary reconnect */
+ continue;
+
+ /* Blocking read on the network socket */
+ cmd = dsi_stream_receive(dsi);
+
+ if (cmd == 0) {
+ /* cmd == 0 is the error condition */
+ if (dsi->flags & DSI_RECONSOCKET) {
+ /* we just got a reconnect so we immediately try again to receive on the new fd */
+ dsi->flags &= ~DSI_RECONSOCKET;
+ continue;
+ }
+
+ /* the client sometimes logs out (afp_logout) but doesn't close the DSI session */
+ if (dsi->flags & DSI_AFP_LOGGED_OUT) {
+ LOG(log_note, logtype_afpd, "afp_over_dsi: client logged out, terminating DSI session");
+ afp_dsi_close(obj);
+ exit(0);
+ }
+
+ if (dsi->flags & DSI_RECONINPROG) {
+ LOG(log_note, logtype_afpd, "afp_over_dsi: failed reconnect");
+ afp_dsi_close(obj);
+ exit(0);
+ }
+
+ /* Some error on the client connection, enter disconnected state */
+ if (dsi_disconnect(dsi) != 0)
+ afp_dsi_die(EXITERR_CLNT);
+
+ ipc_child_state(obj, DSI_DISCONNECTED);
+
+ while (dsi->flags & DSI_DISCONNECTED)
+ pause(); /* gets interrupted by SIGALARM or SIGURG tickle */
+ ipc_child_state(obj, DSI_RUNNING);
+ continue; /* continue receiving until disconnect timer expires
+ * or a primary reconnect succeeds */
+ }
+
+ if (!(dsi->flags & DSI_EXTSLEEP) && (dsi->flags & DSI_SLEEPING)) {
+ LOG(log_debug, logtype_afpd, "afp_over_dsi: got data, ending normal sleep");
+ dsi->flags &= ~DSI_SLEEPING;
+ dsi->tickle = 0;
+ ipc_child_state(obj, DSI_RUNNING);
+ }