/* * Send the current request, after encrypting it. Returns 0 on success, * or -1 on failure. */ static int send_msg(struct tac_handle *h) { struct timeval deadline; struct tac_msg *msg; char *ptr; int len; if (h->last_seq_no & 1) { generr(h, "Attempt to send message out of sequence"); return -1; } if (establish_connection(h) == -1) return -1; msg = &h->request; msg->seq_no = ++h->last_seq_no; if (msg->seq_no == 1) gen_session_id(msg); crypt_msg(h, msg); if (h->single_connect) msg->flags |= TAC_SINGLE_CONNECT; else msg->flags &= ~TAC_SINGLE_CONNECT; gettimeofday(&deadline, NULL); deadline.tv_sec += h->servers[h->cur_server].timeout; len = HDRSIZE + ntohl(msg->length); ptr = (char *)msg; while (len > 0) { int n; n = write(h->fd, ptr, len); if (n == -1) { struct timeval tv; int nfds; if (errno != EAGAIN) { generr(h, "Network write error: %s", strerror(errno)); return -1; } /* Wait until we can write more data. */ gettimeofday(&tv, NULL); timersub(&deadline, &tv, &tv); if (tv.tv_sec >= 0) { fd_set wfds; FD_ZERO(&wfds); FD_SET(h->fd, &wfds); nfds = select(h->fd + 1, NULL, &wfds, NULL, &tv); if (nfds == -1) { generr(h, "select: %s", strerror(errno)); return -1; } } else nfds = 0; if (nfds == 0) { generr(h, "Network write timed out"); return -1; } } else { ptr += n; len -= n; } } return 0; }
int F950999(TRUSERID *handle, int iRequest, ST_PACK *rpack, int *pRetCode, char *szMsg) { char szfile[256]; char full_path[512] = ""; char temp_path[512] = ""; int maxlen,ret,head_len; char temp[5] = ""; int file_len,flag; FILE *fp; ST_SDPACK *psd; char *pend; struct stat fst; memset(&fst,0,sizeof fst); maxlen = 4096; //writelog(LOG_DEBUG,"orign file[%s]total[%d]",rpack->vsmess,rpack->lvol0); // 获取文件存放路径 ret = GetSysParaVal(GLOBAL_UPLOAD_PATH,full_path); if(ret) { *pRetCode = ret; return -1; } // 认为是第一个请求包与最后一个请求包 if(do_get_packtype() == 0) { // 获取文件名, 去掉路径 file_len = rpack->lvol0; pend = strrchr(rpack->vsmess,'/'); if(pend) { if(pend >= strlen(rpack->vsmess) + rpack->vsmess) { *pRetCode = E_INPUT_DATA_INVAILD; return -1; } strcpy(szfile,pend+1); } else strcpy(szfile, rpack->vsmess); strcat(full_path,"/"); strcpy(temp_path,full_path); strcat(full_path,szfile); SetCol(handle,F_LVOL0,F_SCUST_LIMIT, F_VSMESS, 0); if(rpack->lvol1 == 0xFF) { strcat(temp_path,rpack->scust_limit); // 文件结束,判断文件大小 stat(temp_path, &fst); if(fst.st_size != file_len) { *pRetCode = E_UPLOAD_FILE_CRC; writelog(LOG_DEBUG,"upload file[%s] length error,orign[%d],[%d]!" ,full_path,file_len,fst.st_size); return -1; } // 重命名文件 if(rename(temp_path,full_path)) { *pRetCode = E_UPLOAD_CONFLICT; return -1; } writelog(LOG_DEBUG,"upload file[%s] success!",full_path); } else { // 第一个包删除原始文件 unlink(full_path); writelog(LOG_DEBUG,"begin upload file[%s]!",full_path); // 生成session id gen_session_id(rpack->scust_limit,10); } // 返回文件名 rpack->lvol0 = file_len; des2src(rpack->vsmess,szfile); PutRow(handle, rpack, pRetCode, szMsg); return 0; } // 认为是后续包 psd = (ST_SDPACK *)rpack; // 取包头长度 strncpy(temp,psd->data,4); temp[4] = '\0'; head_len = strtoul(temp,NULL,16); if(head_len > psd->usDataLength) { *pRetCode = E_INPUT_DATA_INVAILD; return -1; } // 文件名 strncpy(szfile,psd->data+4,head_len-5); szfile[head_len-5] = '\0'; // 包的标志 flag = psd->data[head_len-1]; // 文件全路径 strcat(full_path,"/"); strcat(full_path,szfile); //writelog(LOG_DEBUG,"write file[%s]",full_path); if(flag != 0xFF) { // 以二进制打开文件 fp = fopen(full_path, "a+b"); if (fp == NULL) { sprintf(szMsg, "Cannot open the file:<%s>!", szfile); *pRetCode = 9980; } else { fwrite(psd->data+head_len,psd->usDataLength-head_len,1,fp); fclose(fp); stat(full_path, &fst); sprintf(szMsg, "%ld", fst.st_mtime); if(flag == 0xFF) { // 文件上传完成,校验文件 } *pRetCode = 0; } } SetCol(handle,F_LVOL0, F_VSMESS, 0); // 文件大小 rpack->lvol0 = fst.st_size; des2src(rpack->vsmess, szMsg); PutRow(handle, rpack, pRetCode, szMsg); return 0; }
namespace updateserver { // 产生的id只是用于检验session是否匹配,可以不唯一, // 因为如果备机传来错误的位置,在读取日志时可以检查到 static int64_t gen_session_id() { int64_t now_us = tbsys::CTimeUtil::getTime(); return now_us; } struct ObLogLocationInfo { ObLogLocationInfo(): version_(cur_version_), location_(), buf_pos_(0) {} ~ObLogLocationInfo() {} static int64_t cur_version_; int64_t version_; ObLogLocation location_; int64_t buf_pos_; int save_to_session(ObSessionBuffer& buf) const { int err = OB_SUCCESS; if (sizeof(*this) > sizeof(buf.data_)) { err = OB_BUF_NOT_ENOUGH; } else { buf.data_len_ = sizeof(*this); *(ObLogLocationInfo*)buf.data_ = *this; } return err; } int restore_from_session(ObSessionBuffer& buf) { int err = OB_SUCCESS; if (buf.data_len_ == 0) {} // 备机第一次连接时使用空session else if (buf.data_len_ != sizeof(*this) || *(int64_t*)buf.data_ != cur_version_) { TBSYS_LOG(WARN, "invalid session: maybe master changed!"); } else { *this = *(ObLogLocationInfo*)buf.data_; } return err; } char* to_str() const { static __thread char buf[OB_MAX_DEBUG_MSG_LEN]; snprintf(buf, sizeof(buf), "location{buf_pos=%ld, log_id=%ld, file=%ld:+%ld}", buf_pos_, location_.log_id_, location_.file_id_, location_.offset_); buf[sizeof(buf)-1] = 0; return buf; } }; int64_t ObLogLocationInfo::cur_version_ = gen_session_id(); int get_local_log(ObPosLogReader* log_reader, ObLogBuffer* log_buffer, ObFetchLogReq& req, ObFetchedLog& fetched_log) { int err = OB_SUCCESS; ObLogLocationInfo location; ObLogLocationInfo end_location; ObFetchLogReq next_req; char* buf = fetched_log.log_data_; int64_t len = min(req.max_data_len_, fetched_log.max_data_len_); int64_t read_count = 0; if (NULL == log_reader || NULL == log_buffer) { err = OB_INVALID_ARGUMENT; } else if (OB_SUCCESS != (err = location.restore_from_session(req.session_))) { TBSYS_LOG(ERROR, "location.deserialize()=>%d", err); } else if (OB_SUCCESS != (err = get_from_log_buffer(log_buffer, OB_DIRECT_IO_ALIGN_BITS, location.buf_pos_, end_location.buf_pos_, req.start_id_, next_req.start_id_, buf, len, read_count)) && OB_DATA_NOT_SERVE != err) { TBSYS_LOG(ERROR, "get_from_log_buffer(start_id=%ld)=>%d", req.start_id_, err); } else if (OB_SUCCESS == err) {} // read from buf else if (OB_SUCCESS != (err = log_reader->get_log(req.start_id_, location.location_, end_location.location_, buf, len, read_count)) && OB_DATA_NOT_SERVE != err) { TBSYS_LOG(ERROR, "pos_log_reader.get_log(start_id=%ld)=>%d", req.start_id_, err); } else if (OB_SUCCESS == err) { next_req.start_id_ = end_location.location_.log_id_; } else { TBSYS_LOG(WARN, "pos_log_reader.get_log(): DATA_NOT_SERVE, maybe slave has more recent log than master."); } if (OB_SUCCESS != err) {} else if (OB_SUCCESS != (err = end_location.save_to_session(next_req.session_))) { TBSYS_LOG(ERROR, "location.deserialize()=>%d", err); } else { fetched_log.start_id_ = req.start_id_; fetched_log.end_id_ = next_req.start_id_; fetched_log.data_len_ = read_count; fetched_log.next_req_ = next_req; } TBSYS_LOG(DEBUG, "get_local_log(log_id=%ld, read_count=%ld)=>%d", req.start_id_, read_count, err); return err; } ObCachedPosLogReader::ObCachedPosLogReader(): log_reader_(NULL), log_buffer_(NULL) {} ObCachedPosLogReader::~ObCachedPosLogReader() {} bool ObCachedPosLogReader::is_inited() const { return NULL != log_reader_ && NULL != log_buffer_; } int ObCachedPosLogReader::init(ObPosLogReader* log_reader, ObLogBuffer* log_buffer) { int err = OB_SUCCESS; if (is_inited()) { err = OB_INIT_TWICE; } else if (NULL == log_reader || NULL == log_buffer) { err = OB_INVALID_ARGUMENT; } else { log_reader_ = log_reader; log_buffer_ = log_buffer; } return err; } int ObCachedPosLogReader:: get_log(ObFetchLogReq& req, ObFetchedLog& result) { int err = OB_SUCCESS; req.max_data_len_ = min(req.max_data_len_, OB_MAX_LOG_BUFFER_SIZE); if (!is_inited()) { err = OB_NOT_INIT; } else if (OB_SUCCESS != (err = get_local_log(log_reader_, log_buffer_, req, result)) && OB_DATA_NOT_SERVE != err) { TBSYS_LOG(ERROR, "get_local_log(req.start_id=%ld)=>%d", req.start_id_, err); } return err; } }; // end namespace updateserver