void afp_free_server(struct afp_server ** sp) { struct dsi_request * p, *next; struct afp_volume * volumes; struct afp_server * server; if (sp==NULL) return; server=*sp; if (!server) return; for (p=server->command_requests;p;) { log_for_client(NULL,AFPFSD,LOG_NOTICE,"FSLeft in queue: %p, id: %d command: %d\n", p,p->requestid,p->subcommand); next=p->next; free(p); p=next; } volumes=server->volumes; loop_disconnect(server); if (server->incoming_buffer) free(server->incoming_buffer); if (server->attention_buffer) free(server->attention_buffer); if (volumes) free(volumes); free(server); *sp=NULL; }
void * dsi_incoming_attention(void * other) { struct afp_server * server = other; struct { struct dsi_header header __attribute__((__packed__)); uint16_t flags ; } __attribute__((__packed__)) *packet = (void *) server->attention_buffer; unsigned short flags; char mesg[AFP_LOGINMESG_LEN]; unsigned char shutdown=0; unsigned char mins=0; unsigned char checkmessage=0; /* The logic here's undocumented. If we get an attention packet and there's no flag, then go check the message. Also, go check the the message if there is a flag and we have the AFPATTN_MESG flag. Checked on netatalk 2.0.3. */ /* It's a bit tough to find docs on this, but I found it at: http://web.archive.org/web/20010806173437/developer.apple.com/techpubs/macosx/Networking/AFPClient/AFPClient-15.html */ if (ntohl(packet->header.length)>=2) { flags=ntohs(packet->flags); if (flags&AFPATTN_MESG) checkmessage=1; if (flags&(AFPATTN_CRASH|AFPATTN_SHUTDOWN)) shutdown=1; mins=flags & 0xff; } else { checkmessage=1; } if (checkmessage) { afp_getsrvrmsg(server,AFPMESG_SERVER, ((server->using_version->av_number>=30)?1:0), DSI_DEFAULT_TIMEOUT,mesg); if(bcmp(mesg,"The server is going down for maintenance.",41)==0) shutdown=1; } if (shutdown) { log_for_client(NULL,AFPFSD,LOG_ERR, "Got a shutdown notice in packet %d, going down in %d mins\n",ntohs(packet->header.requestid),mins); loop_disconnect(server); server->connect_state=SERVER_STATE_DISCONNECTED; return NULL; } return NULL; }
static int process_server_fds(fd_set * set, int max_fd, int ** onfd) { struct afp_server * s; int ret; s = get_server_base(); for (;s;s=s->next) { if (s->next==s) printf("Danger, recursive loop\n"); if (FD_ISSET(s->fd,set)) { ret=dsi_recv(s); *onfd=&s->fd; if (ret==-1) { loop_disconnect(s); return -1; } return 1; } } return 0; }
static unsigned char process_suspend(struct fuse_client * c) { struct afp_server_suspend_request * req =(void *)c->incoming_string+1; struct afp_server * s; /* Find the server */ if ((s=find_server_by_name(req->server_name))==NULL) { log_for_client((void *) c,AFPFSD,LOG_ERR, "%s is an unknown server\n",req->server_name); return AFP_SERVER_RESULT_ERROR; } if (afp_zzzzz(s)) return AFP_SERVER_RESULT_ERROR; loop_disconnect(s); s->connect_state=SERVER_STATE_DISCONNECTED; log_for_client((void *) c,AFPFSD,LOG_NOTICE, "Disconnected from %s\n",req->server_name); return AFP_SERVER_RESULT_OKAY; }
void dsi_incoming_closesession(struct afp_server *server) { afp_unmount_all_volumes(server); loop_disconnect(server); }