/* * Write bytes to a FIFO * Return number of bytes written, or an error code */ int sfifo_write(sfifo_t *f, const void *_buf, int len) { int total; int i; const char *buf = (const char *)_buf; if(!f->buffer) return -ENODEV; /* No buffer! */ /* total = len = min(space, len) */ total = sfifo_space(f); DBG(printf("sfifo_space() = %d\n",total)); if(len > total) len = total; else total = len; i = f->writepos; if(i + len > f->size) { memcpy(f->buffer + i, buf, f->size - i); buf += f->size - i; len -= f->size - i; i = 0; } memcpy(f->buffer + i, buf, len); f->writepos = i + len; return total; }
static int write_coreaudio(audio_output_t *ao, unsigned char *buf, int len) { mpg123_coreaudio_t* ca = (mpg123_coreaudio_t*)ao->userptr; int written; /* If there is no room, then sleep for half the length of the FIFO */ while (sfifo_space( &ca->fifo ) < len ) { usleep( (FIFO_DURATION/2) * 1000000 ); } /* Store converted audio in ring buffer */ written = sfifo_write( &ca->fifo, (char*)buf, len); if (written != len) { warning( "Failed to write audio to ring buffer" ); return -1; } /* Start playback now that we have something to play */ if(!ca->play) { if(AudioOutputUnitStart(ca->outputUnit)) { error("AudioOutputUnitStart failed"); return(-1); } ca->play = 1; } return len; }
static int write_sdl(out123_handle *ao, unsigned char *buf, int len) { sfifo_t *fifo = (sfifo_t*)ao->userptr; /* Sleep for half the length of the FIFO */ while (sfifo_space( fifo ) < len ) #ifdef WIN32 Sleep( (FIFO_DURATION/2) * 1000); #else usleep( (FIFO_DURATION/2) * 1000000 ); #endif /* Bung decoded audio into the FIFO SDL Audio locking probably isn't actually needed as SFIFO claims to be thread safe... */ SDL_LockAudio(); sfifo_write( fifo, buf, len); SDL_UnlockAudio(); /* Unpause once the buffer is 50% full */ if (sfifo_used(fifo) > (sfifo_size(fifo)*0.5) ) SDL_PauseAudio(0); return len; }
static void send_file(struct ftpd_datastate *fsd, struct tcp_pcb *pcb) { if (!fsd->connected) return; if (fsd->vfs_file) { char buffer[2048]; int len; len = sfifo_space(&fsd->fifo); if (len == 0) { send_data(pcb, fsd); return; } if (len > 2048) len = 2048; len = vfs_read(buffer, 1, len, fsd->vfs_file); if (len == 0) { if (vfs_eof(fsd->vfs_file) == 0) return; vfs_close(fsd->vfs_file); fsd->vfs_file = NULL; return; } sfifo_write(&fsd->fifo, buffer, len); send_data(pcb, fsd); } else { struct ftpd_msgstate *fsm; struct tcp_pcb *msgpcb; if (sfifo_used(&fsd->fifo) > 0) { send_data(pcb, fsd); return; } fsm = fsd->msgfs; msgpcb = fsd->msgpcb; vfs_close(fsd->vfs_file); fsd->vfs_file = NULL; ftpd_dataclose(pcb, fsd); fsm->datapcb = NULL; fsm->datafs = NULL; fsm->state = FTPD_IDLE; send_msg(msgpcb, fsm, msg226); return; } }
static void send_msg(struct tcp_pcb *pcb, struct ftpd_msgstate *fsm, char *msg, ...) { va_list arg; char buffer[1024]; int len; va_start(arg, msg); vsprintf(buffer, msg, arg); va_end(arg); strcat(buffer, "\r\n"); len = strlen(buffer); if (sfifo_space(&fsm->fifo) < len) return; sfifo_write(&fsm->fifo, buffer, len); dbg_printf("response: %s", buffer); send_msgdata(pcb, fsm); }
static EEL_xno n2s_getindex(EEL_object *eo, EEL_value *op1, EEL_value *op2) { EB_socket *ebs = o2EB_socket(eo); const char *is; if(!ebs->rs) return EEL_XDEVICECLOSED; is = eel_v2s(op1); if(!is) return EEL_XWRONGTYPE; if(strcmp(is, "index") == 0) op2->integer.v = ebs->rs->n2socket; else if(strcmp(is, "buffer") == 0) { if(ebs->rs->fifo.buffer) op2->integer.v = sfifo_space(&ebs->rs->fifo); else op2->integer.v = 0; } else return EEL_XWRONGINDEX; op2->type = EEL_TINTEGER; return 0; }
static EEL_xno n2_tcp_send(EEL_vm *vm) { EEL_value *args = vm->heap + vm->argv; EB_socket *ebs; int i, count = 0; if(EEL_TYPE(args) != md.net2_socket_cid) return EEL_XWRONGTYPE; ebs = o2EB_socket(args->objref.v); if(!ebs->rs) return EEL_XDEVICECLOSED; if(ebs->rs->status) return ebs->rs->status; for(i = 1; i < vm->argc; ++i) { void *buf; int bsize; EEL_value *v = args + i; switch((EEL_classes)EEL_TYPE(v)) { case EEL_CREAL: { int n; #if SDL_BYTEORDER == SDL_BIG_ENDIAN char lb[sizeof(EEL_real)]; *((EEL_real *)&lb) = v->real.v; #else union { EEL_real r; char c[sizeof(EEL_real)]; } cvt; char lb[sizeof(EEL_real)]; cvt.r = v->real.v; for(n = 0; n < sizeof(EEL_real); ++n) lb[n] = cvt.c[sizeof(EEL_real) - 1 - n]; #endif buf = &lb; bsize = sizeof(EEL_real); break; } case EEL_CINTEGER: { EEL_uint32 cvt; SDLNet_Write32(eel_v2l(v), &cvt); buf = &cvt; bsize = 4; break; } case EEL_CSTRING: case EEL_CDSTRING: { buf = (void *)eel_v2s(v); bsize = eel_length(v->objref.v); break; } default: return EEL_XARGUMENTS; } if(ebs->rs->sender) { /* Buffered, non-blocking */ if(sfifo_space(&ebs->rs->fifo) < bsize) return EEL_XBUFOVERFLOW; sfifo_write(&ebs->rs->fifo, buf, bsize); } else { /* Direct, blocking */ int n = NET2_TCPSend(ebs->rs->n2socket, buf, bsize); if(n < 0) return EEL_XDEVICEWRITE; } count += bsize; } eel_l2v(vm->heap + vm->resv, count); return 0; }
static void send_next_directory(struct ftpd_datastate *fsd, struct tcp_pcb *pcb, int shortlist) { char buffer[1024]; int len; while (1) { if (fsd->vfs_dirent == NULL) fsd->vfs_dirent = vfs_readdir(fsd->vfs_dir); if (fsd->vfs_dirent) { if (shortlist) { len = sprintf(buffer, "%s\r\n", fsd->vfs_dirent->name); if (sfifo_space(&fsd->fifo) < len) { send_data(pcb, fsd); return; } sfifo_write(&fsd->fifo, buffer, len); fsd->vfs_dirent = NULL; } else { vfs_stat_t st; time_t current_time; int current_year; struct tm *s_time; time(¤t_time); s_time = gmtime(¤t_time); current_year = s_time->tm_year; vfs_stat(fsd->msgfs->vfs, fsd->vfs_dirent->name, &st); s_time = gmtime(&st.st_mtime); if (s_time->tm_year == current_year) len = sprintf(buffer, "-rw-rw-rw- 1 user ftp %11ld %s %02i %02i:%02i %s\r\n", st.st_size, month_table[s_time->tm_mon], s_time->tm_mday, s_time->tm_hour, s_time->tm_min, fsd->vfs_dirent->name); else len = sprintf(buffer, "-rw-rw-rw- 1 user ftp %11ld %s %02i %5i %s\r\n", st.st_size, month_table[s_time->tm_mon], s_time->tm_mday, s_time->tm_year + 1900, fsd->vfs_dirent->name); if (VFS_ISDIR(st.st_mode)) buffer[0] = 'd'; if (sfifo_space(&fsd->fifo) < len) { send_data(pcb, fsd); return; } sfifo_write(&fsd->fifo, buffer, len); fsd->vfs_dirent = NULL; } } else { struct ftpd_msgstate *fsm; struct tcp_pcb *msgpcb; if (sfifo_used(&fsd->fifo) > 0) { send_data(pcb, fsd); return; } fsm = fsd->msgfs; msgpcb = fsd->msgpcb; vfs_closedir(fsd->vfs_dir); fsd->vfs_dir = NULL; ftpd_dataclose(pcb, fsd); fsm->datapcb = NULL; fsm->datafs = NULL; fsm->state = FTPD_IDLE; send_msg(msgpcb, fsm, msg226); return; } } }