void obexsrv_put(obex_t *handle, obex_object_t *object) { obex_headerdata_t hv; uint8_t hi; int hlen; const uint8_t *body = NULL; int body_len = 0; char *name = NULL; int endofbody = 0; int len, con_id = -1; char *obj_type = NULL; obexsrv_t *srv = OBEX_GetUserData(handle); int flags = 0, err; DBPRT(""); /* body received. close it */ if (srv->sfd >= 0) { close(srv->sfd); srv->sfd = -1; } while(OBEX_ObjectGetNextHeader(handle, object, &hi, &hv, &hlen)) { switch (hi) { case OBEX_HDR_CONNECTION: con_id = hv.bq4; DBPRT("Found connection id: %08x", con_id); break; case OBEX_HDR_LENGTH: len = hv.bq4; DBPRT("Found Length: %d, hlen: %d", len, hlen); break; case OBEX_HDR_NAME: if ((name = malloc(hlen/2))) { OBEX_UnicodeToChar(name, hv.bs, hlen); } DBPRT("Found name: %s", name); break; case OBEX_HDR_TYPE: obj_type = (char *)hv.bs; DBPRT("Found type:%*s, hlen: %d", hlen, obj_type, hlen); break; case OBEX_HDR_BODY: DBPRT("Found body"); body = hv.bs; body_len = hlen; break; case OBEX_HDR_BODY_END: DBPRT("Found end of body"); endofbody = 1; break; default: DBPRT("Skipped header %02x", hi); break; } } if (!body) { if (endofbody) { DBPRT("Got a PUT with only end of body header->create empty object."); flags |= 0x01; // empty object } else { DBPRT("Got a PUT without a body?????"); if (!srv->streamming) { DBPRT("Got a PUT without a body->delete"); flags |= 0x02; // delete } } } if (!name) { if ((flags & 0x03)) {// empty or delete BTERROR("name is missing."); OBEX_ObjectSetRsp(object, OBEX_RSP_BAD_REQUEST, OBEX_RSP_BAD_REQUEST); goto error; } } // call handler err = srv->put(srv, srv->name, name, obj_type, flags); if (err < 0) { if (errno == ENOENT) OBEX_ObjectSetRsp(object, OBEX_RSP_NOT_FOUND, OBEX_RSP_NOT_FOUND); else OBEX_ObjectSetRsp(object, OBEX_RSP_INTERNAL_SERVER_ERROR, OBEX_RSP_INTERNAL_SERVER_ERROR); if (srv->name) unlink(srv->name); goto error; } OBEX_ObjectSetRsp(object, OBEX_RSP_CONTINUE, OBEX_RSP_SUCCESS); error: if (srv->name) { free(srv->name); srv->name = NULL; } if (name) free(name); }
void obexsrv_setpath(obex_t *handle, obex_object_t *object) { obex_headerdata_t hv; uint8_t hi; int hlen; char *name = NULL; int con_id = -1; uint8_t *nonhdrdata; int flags; int len; obexsrv_t *srv = OBEX_GetUserData(handle); int err; DBPRT(""); if ((len = OBEX_ObjectGetNonHdrData(object, &nonhdrdata)) == 2) { obex_setpath_hdr_t *hdr = (obex_setpath_hdr_t*)nonhdrdata; flags = hdr->flags; DBPRT("Flags= 0x%02x Constants=%d", flags, hdr->constants); } else { BTERROR("Invalid packet content. len=%d", len); flags = 0; } while(OBEX_ObjectGetNextHeader(handle, object, &hi, &hv, &hlen)) { switch(hi) { case OBEX_HDR_NAME: if (hlen) { if ((name = malloc(hlen/2))) OBEX_UnicodeToChar(name, hv.bs, hlen); } else flags |= 0x80; // name exits but zero -> set root DBPRT("Found name: %s", name); break; case OBEX_HDR_CONNECTION: con_id = hv.bq4; DBPRT("Found connection id: %08x", con_id); break; default: DBPRT("Skipped header %02x", hi); break; } } // call handler err = srv->setpath(srv, name, flags); if (err) goto error; OBEX_ObjectSetRsp(object, OBEX_RSP_CONTINUE, OBEX_RSP_SUCCESS); if (name) free(name); return; error: OBEX_ObjectSetRsp(object, OBEX_RSP_NOT_FOUND, OBEX_RSP_NOT_FOUND); if (name) free(name); return; }
static void get_server(obex_t *handle, obex_object_t *object) { uint8_t *buf = NULL; obex_headerdata_t hv; uint8_t hi; uint32_t hlen; int file_size; char *name = NULL; char *type = NULL; printf("%s()\n", __FUNCTION__); while(OBEX_ObjectGetNextHeader(handle, object, &hi, &hv, &hlen)) { switch(hi) { case OBEX_HDR_NAME: printf("%s() Found name\n", __FUNCTION__); if( (name = malloc(hlen / 2))) { OBEX_UnicodeToChar((uint8_t*)name, hv.bs, hlen); printf("name:%s\n", name); } break; case OBEX_HDR_TYPE: if( (type = malloc(hlen + 1))) { strcpy(type, (char *)hv.bs); } printf("%s() type:%s\n", __FUNCTION__, type); case 0xbe: // user-defined inverse push printf("%s() Found inverse push req\n", __FUNCTION__); printf("data:%02x\n", hv.bq1); break; case OBEX_HDR_APPARAM: printf("%s() Found apparam\n", __FUNCTION__); printf("name:%d (%02x %02x ...)\n", hlen, *hv.bs, *(hv.bs+1)); break; default: printf("%s() Skipped header %02x\n", __FUNCTION__, hi); } } //fprintf(stderr, "%s:%d:%s\n", __FILE__, __LINE__, __FUNCTION__); if (is_type_fl(type)) { struct dirent *dirp; DIR *dp; struct stat statdir; struct stat statbuf; char *filename; struct rawdata_stream *xmldata; xmldata = INIT_RAWDATA_STREAM(512); if (NULL == xmldata) goto out; FL_XML_VERSION(xmldata); FL_XML_TYPE(xmldata); FL_XML_BODY_BEGIN(xmldata); stat(CUR_DIR, &statdir); dp = opendir(CUR_DIR); while(NULL != dp && NULL != (dirp = readdir(dp))) { if (0 == strcmp(dirp->d_name, ".") || 0 == strcmp(dirp->d_name, "..")) continue; FL_XML_BODY_ITEM_BEGIN(xmldata); //Adding 1 bytes due to containing '\0' filename = malloc(strlen(CUR_DIR) + strlen(dirp->d_name) + 1); strcpy(filename, CUR_DIR); strcat(filename, dirp->d_name); lstat(filename, &statbuf); if (0 == S_ISDIR(statbuf.st_mode)) //it is a file FL_XML_BODY_FILENAME(xmldata, dirp->d_name); else //it is a directory FL_XML_BODY_FOLDERNAME(xmldata, dirp->d_name); FL_XML_BODY_SIZE(xmldata, statbuf.st_size); FL_XML_BODY_PERM(xmldata, statbuf.st_mode, statdir.st_mode); FL_XML_BODY_MTIME(xmldata, statbuf.st_mtime); FL_XML_BODY_CTIME(xmldata, statbuf.st_ctime); FL_XML_BODY_ATIME(xmldata, statbuf.st_atime); FL_XML_BODY_ITEM_END(xmldata); //printf("---filename:%s\n", filename); //fprintf(stderr, "%s:%d:%s\n", __FILE__, __LINE__, __FUNCTION__); free(filename); filename = NULL; //fprintf(stderr, "%s:%d:%s\n", __FILE__, __LINE__, __FUNCTION__); } //fprintf(stderr, "%s:%d:%s\n", __FILE__, __LINE__, __FUNCTION__); FL_XML_BODY_END(xmldata); closedir(dp); printf("xml doc:%s\n", xmldata->data); //composite the obex obejct OBEX_ObjectSetRsp(object, OBEX_RSP_CONTINUE, OBEX_RSP_SUCCESS); hv.bs = (uint8_t *)xmldata->data; OBEX_ObjectAddHeader(handle, object, OBEX_HDR_BODY, hv, xmldata->size, 0); hv.bq4 = xmldata->size; OBEX_ObjectAddHeader(handle, object, OBEX_HDR_LENGTH, hv, sizeof(uint32_t), 0); //fprintf(stderr, "%s:%d:%s\n", __FILE__, __LINE__, __FUNCTION__); FREE_RAWDATA_STREAM(xmldata); //fprintf(stderr, "%s:%d:%s\n", __FILE__, __LINE__, __FUNCTION__); } else if (name) { printf("%s() Got a request for %s\n", __FUNCTION__, name); buf = easy_readfile(name, &file_size); if(buf == NULL) { printf("Can't find file %s\n", name); OBEX_ObjectSetRsp(object, OBEX_RSP_NOT_FOUND, OBEX_RSP_NOT_FOUND); return; } OBEX_ObjectSetRsp(object, OBEX_RSP_CONTINUE, OBEX_RSP_SUCCESS); hv.bs = buf; OBEX_ObjectAddHeader(handle, object, OBEX_HDR_BODY, hv, file_size, 0); hv.bq4 = file_size; OBEX_ObjectAddHeader(handle, object, OBEX_HDR_LENGTH, hv, sizeof(uint32_t), 0); } else { printf("%s() Got a GET without a name-header!\n", __FUNCTION__); OBEX_ObjectSetRsp(object, OBEX_RSP_NOT_FOUND, OBEX_RSP_NOT_FOUND); return; } //fprintf(stderr, "%s:%d:%s\n", __FILE__, __LINE__, __FUNCTION__); if (NULL != buf) { free(buf); } //fprintf(stderr, "%s:%d:%s\n", __FILE__, __LINE__, __FUNCTION__); out: if (NULL != name) { free(name); } //fprintf(stderr, "%s:%d:%s\n", __FILE__, __LINE__, __FUNCTION__); if (NULL != type) { free(type); } //fprintf(stderr, "%s:%d:%s\n", __FILE__, __LINE__, __FUNCTION__); return; }
void obexsrv_get(obex_t *handle, obex_object_t *object) { obex_headerdata_t hv; uint8_t hi; int hlen; char *obj_type = NULL; char *name = NULL; int con_id = -1; obexsrv_t *srv = OBEX_GetUserData(handle); int err; DBPRT(""); while(OBEX_ObjectGetNextHeader(handle, object, &hi, &hv, &hlen)) { switch(hi) { case OBEX_HDR_NAME: if ((name = malloc(hlen/2))) { OBEX_UnicodeToChar(name, hv.bs, hlen); } DBPRT(" Found name: %s", name); break; case OBEX_HDR_TYPE: obj_type = (char *)hv.bs; DBPRT(" Found type:%-30s", obj_type); break; case OBEX_HDR_CONNECTION: con_id = hv.bq4; DBPRT(" Found connection id: %08x", con_id); break; default: DBPRT(" Skipped header %02x", hi); break; } } /* call handler */ err = srv->get(srv, name, obj_type); if (err < 0 || !srv->name) { DBPRT("File not found: %s\n", name); OBEX_ObjectSetRsp(object, OBEX_RSP_NOT_FOUND, OBEX_RSP_NOT_FOUND); return; } srv->sfd = open(srv->name, O_RDONLY); if (srv->sfd < 0) { OBEX_ObjectSetRsp(object, OBEX_RSP_NOT_FOUND, OBEX_RSP_NOT_FOUND); return; } srv->buf = malloc(OBEX_STREAM_CHUNK); if (!srv->buf) { OBEX_ObjectSetRsp(object, OBEX_RSP_INTERNAL_SERVER_ERROR, OBEX_RSP_INTERNAL_SERVER_ERROR); return; } OBEX_ObjectSetRsp(object, OBEX_RSP_CONTINUE, OBEX_RSP_SUCCESS); hv.bq4 = get_fdsize(srv->sfd); OBEX_ObjectAddHeader(handle, object, OBEX_HDR_LENGTH, hv, sizeof(uint32_t), 0); hv.bs = NULL; OBEX_ObjectAddHeader(handle, object, OBEX_HDR_BODY, hv, 0, OBEX_FL_STREAM_START); if (name) free(name); return; }
static void set_server_path(obex_t *handle, obex_object_t *object) { char *name = NULL; char fullname[WORK_PATH_MAX]; // "Backup Level" and "Don't Create" flag in first byte uint8_t setpath_nohdr_dummy = 0; uint8_t *setpath_nohdr_data; obex_headerdata_t hv; uint8_t hi; uint32_t hlen; OBEX_ObjectGetNonHdrData(object, &setpath_nohdr_data); if (NULL == setpath_nohdr_data) { setpath_nohdr_data = &setpath_nohdr_dummy; printf("nohdr data not found\n"); } printf("nohdr data: %x\n", *setpath_nohdr_data); while(OBEX_ObjectGetNextHeader(handle, object, &hi, &hv, &hlen)) { switch(hi) { case OBEX_HDR_NAME: printf("%s() Found name\n", __FUNCTION__); if (0 < hlen) { if( (name = malloc(hlen / 2))) { OBEX_UnicodeToChar((uint8_t*)name, hv.bs, hlen); printf("name:%s\n", name); } } else { if (verbose) printf("set path to root\n"); chdir(init_work_path); } break; default: printf("%s() Skipped header %02x\n", __FUNCTION__, hi); } } if (name) { if (strstr(name, "/../")) { OBEX_ObjectSetRsp(object, OBEX_RSP_CONTINUE, OBEX_RSP_FORBIDDEN); } else { strcpy(fullname, CUR_DIR); strncat(fullname, name, sizeof(fullname)-1); if ((*setpath_nohdr_data & 2) == 0) { if (verbose) printf("mkdir %s\n", name); if (mkdir(fullname, 0755) < 0) { perror("requested mkdir failed"); } } if (verbose) printf("Set path to %s\n",fullname); if (chdir(fullname) < 0) { perror("requested chdir failed\n"); OBEX_ObjectSetRsp(object, OBEX_RSP_CONTINUE, OBEX_RSP_FORBIDDEN); } } free(name); name = NULL; } }