PRIVATE int msg_close(int minor_dev_nr) { int r, read_chan, write_chan, io_ctl; special_file_t* special_file_ptr; dprint("%s: msg_close() minor device %d\n", drv.DriverName, minor_dev_nr); special_file_ptr = get_special_file(minor_dev_nr); if(special_file_ptr == NULL) { return EIO; } read_chan = special_file_ptr->read_chan; write_chan = special_file_ptr->write_chan; io_ctl = special_file_ptr->io_ctl; /* close all sub devices */ if (write_chan != NO_CHANNEL) { if (close_sub_dev(write_chan) != OK) r = EIO; } if (read_chan != NO_CHANNEL) { if (close_sub_dev(read_chan) != OK) r = EIO; } if (read_chan == io_ctl || write_chan == io_ctl) { /* io_ctl is already closed because it's the same as read or write */ return r; /* we're done */ } /* Ioctl differs from read/write channels... */ if (io_ctl != NO_CHANNEL) { if (close_sub_dev(io_ctl) != OK) r = EIO; /* ...close it explicitly */ } return r; }
int ftp_to_fs(const char *ftp, char *fs) { int i; if (strcmp(ftp, "/") == 0) return FALSE; #ifdef USE_SPECIAL_FILE if (get_special_file(ftp) != file_INVALID) return FALSE; #endif if (ftp[2] != 0 && ftp[2] != '/') return FALSE; sprintf(fs, "%c:\\", ftp[1]); if (ftp[2] != 0) { strcpy(&fs[3], &ftp[3]); for (i = 3; fs[i] != 0; i++) if (fs[i] == '/') fs[i] = '\\'; } return TRUE; }
PRIVATE int msg_open (int minor_dev_nr) { int r, read_chan, write_chan, io_ctl; special_file_t* special_file_ptr; dprint("%s: msg_open() special file %d\n", drv.DriverName, minor_dev_nr); special_file_ptr = get_special_file(minor_dev_nr); if(special_file_ptr == NULL) { return EIO; } read_chan = special_file_ptr->read_chan; write_chan = special_file_ptr->write_chan; io_ctl = special_file_ptr->io_ctl; if (read_chan==NO_CHANNEL && write_chan==NO_CHANNEL && io_ctl==NO_CHANNEL) { error("%s: No channel specified for minor device!\n", drv.DriverName, minor_dev_nr); return EIO; } if (read_chan == write_chan && read_chan != NO_CHANNEL) { error("%s: Read and write channels are equal!\n", drv.DriverName, minor_dev_nr); return EIO; } /* init driver */ if (!device_available) { if (init_driver() != OK) { error("%s: Couldn't init driver!\n", drv.DriverName, minor_dev_nr); return EIO; } else { device_available = TRUE; } } /* open the sub devices specified in the interface header file */ if (write_chan != NO_CHANNEL) { /* open sub device for writing */ if (open_sub_dev(write_chan, DEV_WRITE_S) != OK) return EIO; } if (read_chan != NO_CHANNEL) { if (open_sub_dev(read_chan, DEV_READ_S) != OK) return EIO; } if (read_chan == io_ctl || write_chan == io_ctl) { /* io_ctl is already opened because it's the same as read or write */ return OK; /* we're done */ } if (io_ctl != NO_CHANNEL) { /* Ioctl differs from read/write channels, */ r = open_sub_dev(io_ctl, NO_DMA); /* open it explicitly */ if (r != OK) return EIO; } return OK; }
PRIVATE void msg_read(message *m_ptr) { int s, chan; sub_dev_t *sub_dev_ptr; special_file_t* special_file_ptr; dprint("%s: msg_read() device %d\n", drv.DriverName, m_ptr->DEVICE); special_file_ptr = get_special_file(m_ptr->DEVICE); chan = special_file_ptr->read_chan; if (chan == NO_CHANNEL) { error("%s: No read channel specified!\n", drv.DriverName); reply(TASK_REPLY, m_ptr->m_source, m_ptr->PROC_NR, EIO); return; } /* get pointer to sub device data */ sub_dev_ptr = &sub_dev[chan]; if (!sub_dev_ptr->DmaBusy) { /* get fragment size on first read */ if (drv_get_frag_size(&(sub_dev_ptr->FragSize), sub_dev_ptr->Nr) != OK){ error("%s: Could not retrieve fragment size!\n", drv.DriverName); reply(TASK_REPLY, m_ptr->m_source, m_ptr->PROC_NR, EIO); return; } } if(m_ptr->COUNT != sub_dev_ptr->FragSize) { reply(TASK_REPLY, m_ptr->m_source, m_ptr->PROC_NR, EINVAL); error("fragment size does not match message size\n"); return; } /* if we are busy with something else than reading, reply EBUSY */ if(sub_dev_ptr->DmaBusy && sub_dev_ptr->DmaMode != DEV_READ) { reply(TASK_REPLY, m_ptr->m_source, m_ptr->PROC_NR, EBUSY); return; } /* unblock the FileSystem, but keep user process blocked until REVIVE*/ reply(TASK_REPLY, m_ptr->m_source, m_ptr->PROC_NR, SUSPEND); sub_dev_ptr->RevivePending = TRUE; sub_dev_ptr->ReviveProcNr = m_ptr->PROC_NR; sub_dev_ptr->UserBuf = m_ptr->ADDRESS; sub_dev_ptr->NotifyProcNr = m_ptr->m_source; if(!sub_dev_ptr->DmaBusy) { /* Dma tranfer not yet started */ get_started(sub_dev_ptr); sub_dev_ptr->DmaMode = DEV_READ; /* Dma mode is reading */ return; /* no need to get data from DMA buffer at this point */ } /* check if data is available and possibly fill user's buffer */ data_to_user(sub_dev_ptr); }
PRIVATE void msg_write(message *m_ptr) { int s, chan; sub_dev_t *sub_dev_ptr; special_file_t* special_file_ptr; dprint("%s: msg_write() device %d\n", drv.DriverName, m_ptr->DEVICE); special_file_ptr = get_special_file(m_ptr->DEVICE); chan = special_file_ptr->write_chan; if (chan == NO_CHANNEL) { error("%s: No write channel specified!\n", drv.DriverName); reply(TASK_REPLY, m_ptr->m_source, m_ptr->PROC_NR, EIO); return; } /* get pointer to sub device data */ sub_dev_ptr = &sub_dev[chan]; if (!sub_dev_ptr->DmaBusy) { /* get fragment size on first write */ if (drv_get_frag_size(&(sub_dev_ptr->FragSize), sub_dev_ptr->Nr) != OK){ error("%s; Failed to get fragment size!\n", drv.DriverName, 0); return; } } if(m_ptr->COUNT != sub_dev_ptr->FragSize) { error("Fragment size does not match user's buffer length\n"); reply(TASK_REPLY, m_ptr->m_source, m_ptr->PROC_NR, EINVAL); return; } /* if we are busy with something else than writing, return EBUSY */ if(sub_dev_ptr->DmaBusy && sub_dev_ptr->DmaMode != DEV_WRITE) { error("Already busy with something else then writing\n"); reply(TASK_REPLY, m_ptr->m_source, m_ptr->PROC_NR, EBUSY); return; } /* unblock the FileSystem, but keep user process blocked until REVIVE*/ reply(TASK_REPLY, m_ptr->m_source, m_ptr->PROC_NR, SUSPEND); sub_dev_ptr->RevivePending = TRUE; sub_dev_ptr->ReviveProcNr = m_ptr->PROC_NR; sub_dev_ptr->UserBuf = m_ptr->ADDRESS; sub_dev_ptr->NotifyProcNr = m_ptr->m_source; data_from_user(sub_dev_ptr); if(!sub_dev_ptr->DmaBusy) { /* Dma tranfer not yet started */ dprint("starting audio device\n"); get_started(sub_dev_ptr); sub_dev_ptr->DmaMode = DEV_WRITE; /* Dma mode is writing */ } }
PRIVATE int msg_ioctl(message *m_ptr) { int status, len, chan; phys_bytes user_phys; sub_dev_t *sub_dev_ptr; special_file_t* special_file_ptr; dprint("%s: msg_ioctl() device %d\n", drv.DriverName, m_ptr->DEVICE); special_file_ptr = get_special_file(m_ptr->DEVICE); if(special_file_ptr == NULL) { return EIO; } chan = special_file_ptr->io_ctl; if (chan == NO_CHANNEL) { error("%s: No io control channel specified!\n", drv.DriverName); return EIO; } /* get pointer to sub device data */ sub_dev_ptr = &sub_dev[chan]; if(!sub_dev_ptr->Opened) { error("%s: io control impossible - not opened!\n", drv.DriverName); return EIO; } /* this is a hack...todo: may we intercept reset calls? */ if(m_ptr->REQUEST == DSPIORESET) { device_available = FALSE; } /* this is confusing, _IOC_OUT bit means that there is incoming data */ if (m_ptr->REQUEST & _IOC_OUT) { /* if there is data for us, copy it */ len = io_ctl_length(m_ptr->REQUEST); sys_vircopy(m_ptr->PROC_NR, D, (vir_bytes)m_ptr->ADDRESS, SELF, D, (vir_bytes)io_ctl_buf, len); } /* all ioctl's are passed to the device specific part of the driver */ status = drv_io_ctl(m_ptr->REQUEST, (void *)io_ctl_buf, &len, chan); /* _IOC_IN bit -> user expects data */ if (status == OK && m_ptr->REQUEST & _IOC_IN) { /* copy result back to user */ sys_vircopy(SELF, D, (vir_bytes)io_ctl_buf, m_ptr->PROC_NR, D, (vir_bytes)m_ptr->ADDRESS, len); } return status; }
int do_RETR(ftp_session *s, char *param) { int len; char arg[MAX_FTP_PATH], ftp_dir[MAX_FTP_PATH], buf[MAX_BUFFER]; FILE *fp; size_t read, write; SOCKET sockfd; #ifdef USE_SPECIAL_FILE int type, start, size; char *mem; #endif MATCH_SP(param); len = get_string(param, arg, sizeof(arg)); if (len == 0) return 501; param += len; MATCH_CRLF(param); if (!parse_dir(s->dir, arg, ftp_dir)) return 550; #ifndef USE_SPECIAL_FILE if (!ftp_to_fs_read(ftp_dir, arg)) return 550; #else type = get_special_file(ftp_dir); if (type == file_INVALID && !ftp_to_fs_read(ftp_dir, arg)) return 550; if (type != file_INVALID) { start = 0; switch (type) { #ifdef USE_SCREEN_BMP case file_SCREEN_BMP: mem = create_snapshot(&size); if (mem == NULL) return 450; break; #endif #ifdef USE_SCREEN_JPG case file_SCREEN_ZIP: { mem = create_jpeg(&size); if (mem == NULL) return 450; break; } #endif default: return 450; } } else #endif { fp = fopen(arg, "rb"); if (fp == NULL) return 450; } if (s->prev_command == cmd_REST) { #ifdef USE_SPECIAL_FILE if (type != file_INVALID) start = s->restart; else #endif fseek(fp, s->restart, SEEK_SET); } ftp_printf(s->control, reply_150); sockfd = ftp_connect(s); if (sockfd == -1) { #ifdef USE_SPECIAL_FILE if (type != file_INVALID) free(mem); else #endif fclose(fp); return 425; } #ifdef USE_SPECIAL_FILE if (type != file_INVALID) { write = my_send(sockfd, &mem[start], size-start, 0); free(mem); if (write != size-start) { closesocket(sockfd); return 426; } } else #endif { while (!feof(fp)) { s->tick = GetTickCount(); read = fread(buf, 1, sizeof(buf), fp); if (ferror(fp)) { closesocket(sockfd); fclose(fp); return 451; } write = my_send(sockfd, buf, read, 0); if (read != write) { closesocket(sockfd); fclose(fp); return 426; } } fclose(fp); } closesocket(sockfd); return 226; }