static int seek(stream_t *s,off_t newpos) { struct stream_priv_s* p = s->priv; int resp; char rsp_txt[256]; if(s->pos > s->end_pos) { s->eof=1; return 0; } // Check to see if the server did not already terminate the transfer if(fd_can_read(p->handle, 0)) { if(readresp(p,rsp_txt) != 2) mp_msg(MSGT_OPEN,MSGL_WARN, "[ftp] Warning the server didn't finished the transfer correctly: %s\n",rsp_txt); closesocket(s->fd); s->fd = -1; } // Close current download if(s->fd >= 0) { static const char pre_cmd[]={TELNET_IAC,TELNET_IP,TELNET_IAC,TELNET_SYNCH}; //int fl; // First close the fd closesocket(s->fd); s->fd = 0; // Send send the telnet sequence needed to make the server react // Dunno if this is really needed, lftp have it. I let // it here in case it turn out to be needed on some other OS //fl=fcntl(p->handle,F_GETFL); //fcntl(p->handle,F_SETFL,fl&~O_NONBLOCK); // send only first byte as OOB due to OOB braindamage in many unices send(p->handle,pre_cmd,1,MSG_OOB); send(p->handle,pre_cmd+1,sizeof(pre_cmd)-1,0); //fcntl(p->handle,F_SETFL,fl); // Get the 426 Transfer aborted // Or the 226 Transfer complete resp = readresp(p,rsp_txt); if(resp != 4 && resp != 2) { mp_msg(MSGT_OPEN,MSGL_ERR, "[ftp] Server didn't abort correctly: %s\n",rsp_txt); s->eof = 1; return 0; } // Send the ABOR command // Ignore the return code as sometimes it fail with "nothing to abort" FtpSendCmd("ABOR",p,rsp_txt); } return FtpOpenData(s,newpos); }
/* read from socket and write to buffer */ int decoder_buf_read(void) { int len = 0; int count = 0; char header[PIPE_HEADER_LEN]; #define MAX_LOOP 1 #if 0 fprintf(stderr, "decoder_buf_read\n"); #endif len=0; memset(header, 0, PIPE_HEADER_LEN); while (fd_can_read(fd,1000) && count++ < MAX_LOOP) { if (BUFFER_NEXT(head) == tail) { /* buffer full */ return -1; } /* TODO:呼出す関数はfd_canでもブロックされ得る,要改良 */ len = pipe_blocked_read_message(fd, header,dbuf[head].buf,buf_size); #if 1 { static int c=0; d3_printf(" (%3d): len=%d\n", c++, len); } #endif if (len > 0) { dbuf[head].len = len; dbuf[head].ts=pipe_get_timestamp(header); d3_printf(" TS%8x\n",dbuf[head].ts); head = BUFFER_NEXT(head); } #if 0 else if (len < 0) { dbuf[head].len = -2; /* end marker */ head = BUFFER_NEXT(head); //sock_close(); } else { /* len == 0 */ dbuf[head].len = 0; /* ????? */ head = BUFFER_NEXT(head); break; } #else else if(len==PIPE_END || len==PIPE_ERROR){ len=0; dbuf[head].len = -1; /* end marker */ head = BUFFER_NEXT(head); break; } #endif }
static int fill_buffer(stream_t *s, char* buffer, int max_len){ int r; if(s->fd < 0 && !FtpOpenData(s,s->pos)) return -1; if(!fd_can_read(s->fd, 15)) { mp_msg(MSGT_OPEN,MSGL_ERR, "[ftp] read timed out\n"); return -1; } r = recv(s->fd,buffer,max_len,0); return (r <= 0) ? -1 : r; }
/* * read a line of text * * return -1 on error or bytecount */ static int readline(char *buf,int max,struct stream_priv_s *ctl) { int x,retval = 0; char *end,*bp=buf; int eof = 0; do { if (ctl->cavail > 0) { x = (max >= ctl->cavail) ? ctl->cavail : max-1; end = memccpy(bp,ctl->cget,'\n',x); if (end != NULL) x = end - bp; retval += x; bp += x; *bp = '\0'; max -= x; ctl->cget += x; ctl->cavail -= x; if (end != NULL) { bp -= 2; if (strcmp(bp,"\r\n") == 0) { *bp++ = '\n'; *bp++ = '\0'; --retval; } break; } } if (max == 1) { *buf = '\0'; break; } if (ctl->cput == ctl->cget) { ctl->cput = ctl->cget = ctl->buf; ctl->cavail = 0; ctl->cleft = BUFSIZE; } if(eof) { if (retval == 0) retval = -1; break; } if(!fd_can_read(ctl->handle, 15)) { mp_msg(MSGT_OPEN,MSGL_ERR, "[ftp] read timed out\n"); retval = -1; break; } if ((x = recv(ctl->handle,ctl->cput,ctl->cleft,0)) == -1) { mp_msg(MSGT_STREAM,MSGL_ERR, "[ftp] read error: %s\n",strerror(errno)); retval = -1; break; } if (x == 0) eof = 1; ctl->cleft -= x; ctl->cavail += x; ctl->cput += x; } while (1); return retval; }