/* test readx ops */ static BOOL test_readx(struct smbcli_state *cli, TALLOC_CTX *mem_ctx) { union smb_read io; NTSTATUS status; BOOL ret = True; int fnum; uint8_t *buf; const int maxsize = 90000; const char *fname = BASEDIR "\\test.txt"; const char *test_data = "TEST DATA"; uint_t seed = time(NULL); buf = talloc_zero_size(mem_ctx, maxsize); if (!torture_setup_dir(cli, BASEDIR)) { return False; } printf("Testing RAW_READ_READX\n"); fnum = smbcli_open(cli->tree, fname, O_RDWR|O_CREAT, DENY_NONE); if (fnum == -1) { printf("Failed to create %s - %s\n", fname, smbcli_errstr(cli->tree)); ret = False; goto done; } printf("Trying empty file read\n"); io.generic.level = RAW_READ_READX; io.readx.in.file.fnum = fnum; io.readx.in.mincnt = 1; io.readx.in.maxcnt = 1; io.readx.in.offset = 0; io.readx.in.remaining = 0; io.readx.in.read_for_execute = False; io.readx.out.data = buf; status = smb_raw_read(cli->tree, &io); CHECK_STATUS(status, NT_STATUS_OK); CHECK_VALUE(io.readx.out.nread, 0); CHECK_VALUE(io.readx.out.remaining, 0xFFFF); CHECK_VALUE(io.readx.out.compaction_mode, 0); printf("Trying zero file read\n"); io.readx.in.mincnt = 0; io.readx.in.maxcnt = 0; status = smb_raw_read(cli->tree, &io); CHECK_STATUS(status, NT_STATUS_OK); CHECK_VALUE(io.readx.out.nread, 0); CHECK_VALUE(io.readx.out.remaining, 0xFFFF); CHECK_VALUE(io.readx.out.compaction_mode, 0); printf("Trying bad fnum\n"); io.readx.in.file.fnum = fnum+1; status = smb_raw_read(cli->tree, &io); CHECK_STATUS(status, NT_STATUS_INVALID_HANDLE); io.readx.in.file.fnum = fnum; smbcli_write(cli->tree, fnum, 0, test_data, 0, strlen(test_data)); printf("Trying small read\n"); io.readx.in.file.fnum = fnum; io.readx.in.offset = 0; io.readx.in.remaining = 0; io.readx.in.read_for_execute = False; io.readx.in.mincnt = strlen(test_data); io.readx.in.maxcnt = strlen(test_data); status = smb_raw_read(cli->tree, &io); CHECK_STATUS(status, NT_STATUS_OK); CHECK_VALUE(io.readx.out.nread, strlen(test_data)); CHECK_VALUE(io.readx.out.remaining, 0xFFFF); CHECK_VALUE(io.readx.out.compaction_mode, 0); if (memcmp(buf, test_data, strlen(test_data)) != 0) { ret = False; printf("incorrect data at %d!? (%s:%s)\n", __LINE__, test_data, buf); goto done; } printf("Trying short read\n"); io.readx.in.offset = 1; io.readx.in.mincnt = strlen(test_data); io.readx.in.maxcnt = strlen(test_data); status = smb_raw_read(cli->tree, &io); CHECK_STATUS(status, NT_STATUS_OK); CHECK_VALUE(io.readx.out.nread, strlen(test_data)-1); CHECK_VALUE(io.readx.out.remaining, 0xFFFF); CHECK_VALUE(io.readx.out.compaction_mode, 0); if (memcmp(buf, test_data+1, strlen(test_data)-1) != 0) { ret = False; printf("incorrect data at %d!? (%s:%s)\n", __LINE__, test_data+1, buf); goto done; } if (cli->transport->negotiate.capabilities & CAP_LARGE_FILES) { printf("Trying max offset\n"); io.readx.in.offset = 0xffffffff; io.readx.in.mincnt = strlen(test_data); io.readx.in.maxcnt = strlen(test_data); status = smb_raw_read(cli->tree, &io); CHECK_STATUS(status, NT_STATUS_OK); CHECK_VALUE(io.readx.out.nread, 0); CHECK_VALUE(io.readx.out.remaining, 0xFFFF); CHECK_VALUE(io.readx.out.compaction_mode, 0); } setup_buffer(buf, seed, maxsize); smbcli_write(cli->tree, fnum, 0, buf, 0, maxsize); memset(buf, 0, maxsize); printf("Trying large read\n"); io.readx.in.offset = 0; io.readx.in.mincnt = 0xFFFF; io.readx.in.maxcnt = 0xFFFF; status = smb_raw_read(cli->tree, &io); CHECK_STATUS(status, NT_STATUS_OK); CHECK_VALUE(io.readx.out.remaining, 0xFFFF); CHECK_VALUE(io.readx.out.compaction_mode, 0); CHECK_VALUE(io.readx.out.nread, io.readx.in.maxcnt); CHECK_BUFFER(buf, seed, io.readx.out.nread); printf("Trying extra large read\n"); io.readx.in.offset = 0; io.readx.in.mincnt = 100; io.readx.in.maxcnt = 80000; status = smb_raw_read(cli->tree, &io); CHECK_STATUS(status, NT_STATUS_OK); CHECK_VALUE(io.readx.out.remaining, 0xFFFF); CHECK_VALUE(io.readx.out.compaction_mode, 0); if (lp_parm_bool(-1, "torture", "samba3", False)) { printf("SAMBA3: large read extension\n"); CHECK_VALUE(io.readx.out.nread, 80000); } else { CHECK_VALUE(io.readx.out.nread, 0); } CHECK_BUFFER(buf, seed, io.readx.out.nread); printf("Trying mincnt > maxcnt\n"); memset(buf, 0, maxsize); io.readx.in.offset = 0; io.readx.in.mincnt = 30000; io.readx.in.maxcnt = 20000; status = smb_raw_read(cli->tree, &io); CHECK_STATUS(status, NT_STATUS_OK); CHECK_VALUE(io.readx.out.remaining, 0xFFFF); CHECK_VALUE(io.readx.out.compaction_mode, 0); CHECK_VALUE(io.readx.out.nread, io.readx.in.maxcnt); CHECK_BUFFER(buf, seed, io.readx.out.nread); printf("Trying mincnt < maxcnt\n"); memset(buf, 0, maxsize); io.readx.in.offset = 0; io.readx.in.mincnt = 20000; io.readx.in.maxcnt = 30000; status = smb_raw_read(cli->tree, &io); CHECK_STATUS(status, NT_STATUS_OK); CHECK_VALUE(io.readx.out.remaining, 0xFFFF); CHECK_VALUE(io.readx.out.compaction_mode, 0); CHECK_VALUE(io.readx.out.nread, io.readx.in.maxcnt); CHECK_BUFFER(buf, seed, io.readx.out.nread); if (cli->transport->negotiate.capabilities & CAP_LARGE_READX) { printf("Trying large readx\n"); io.readx.in.offset = 0; io.readx.in.mincnt = 0; io.readx.in.maxcnt = 0x10000 - 1; status = smb_raw_read(cli->tree, &io); CHECK_STATUS(status, NT_STATUS_OK); CHECK_VALUE(io.readx.out.nread, 0xFFFF); io.readx.in.maxcnt = 0x10000; status = smb_raw_read(cli->tree, &io); CHECK_STATUS(status, NT_STATUS_OK); if (lp_parm_bool(-1, "torture", "samba3", False)) { printf("SAMBA3: large read extension\n"); CHECK_VALUE(io.readx.out.nread, 0x10000); } else { CHECK_VALUE(io.readx.out.nread, 0); } io.readx.in.maxcnt = 0x10001; status = smb_raw_read(cli->tree, &io); CHECK_STATUS(status, NT_STATUS_OK); if (lp_parm_bool(-1, "torture", "samba3", False)) { printf("SAMBA3: large read extension\n"); CHECK_VALUE(io.readx.out.nread, 0x10001); } else { CHECK_VALUE(io.readx.out.nread, 0); } } printf("Trying locked region\n"); cli->session->pid++; if (NT_STATUS_IS_ERR(smbcli_lock(cli->tree, fnum, 103, 1, 0, WRITE_LOCK))) { printf("Failed to lock file at %d\n", __LINE__); ret = False; goto done; } cli->session->pid--; memset(buf, 0, maxsize); io.readx.in.offset = 0; io.readx.in.mincnt = 100; io.readx.in.maxcnt = 200; status = smb_raw_read(cli->tree, &io); CHECK_STATUS(status, NT_STATUS_FILE_LOCK_CONFLICT); if (!(cli->transport->negotiate.capabilities & CAP_LARGE_FILES)) { printf("skipping large file tests - CAP_LARGE_FILES not set\n"); goto done; } printf("Trying large offset read\n"); io.readx.in.offset = ((uint64_t)0x2) << 32; io.readx.in.mincnt = 10; io.readx.in.maxcnt = 10; status = smb_raw_read(cli->tree, &io); CHECK_STATUS(status, NT_STATUS_OK); CHECK_VALUE(io.readx.out.nread, 0); if (NT_STATUS_IS_ERR(smbcli_lock64(cli->tree, fnum, io.readx.in.offset, 1, 0, WRITE_LOCK))) { printf("Failed to lock file at %d\n", __LINE__); ret = False; goto done; } status = smb_raw_read(cli->tree, &io); CHECK_STATUS(status, NT_STATUS_OK); CHECK_VALUE(io.readx.out.nread, 0); done: smbcli_close(cli->tree, fnum); smbcli_deltree(cli->tree, BASEDIR); return ret; }
/* test lockread ops */ static BOOL test_lockread(struct smbcli_state *cli, TALLOC_CTX *mem_ctx) { union smb_read io; NTSTATUS status; BOOL ret = True; int fnum; uint8_t *buf; const int maxsize = 90000; const char *fname = BASEDIR "\\test.txt"; const char *test_data = "TEST DATA"; uint_t seed = time(NULL); buf = talloc_zero_size(mem_ctx, maxsize); if (!torture_setup_dir(cli, BASEDIR)) { return False; } printf("Testing RAW_READ_LOCKREAD\n"); io.generic.level = RAW_READ_LOCKREAD; fnum = smbcli_open(cli->tree, fname, O_RDWR|O_CREAT, DENY_NONE); if (fnum == -1) { printf("Failed to create %s - %s\n", fname, smbcli_errstr(cli->tree)); ret = False; goto done; } printf("Trying empty file read\n"); io.lockread.in.file.fnum = fnum; io.lockread.in.count = 1; io.lockread.in.offset = 1; io.lockread.in.remaining = 0; io.lockread.out.data = buf; status = smb_raw_read(cli->tree, &io); CHECK_STATUS(status, NT_STATUS_OK); CHECK_VALUE(io.lockread.out.nread, 0); status = smb_raw_read(cli->tree, &io); CHECK_STATUS(status, NT_STATUS_LOCK_NOT_GRANTED); status = smb_raw_read(cli->tree, &io); CHECK_STATUS(status, NT_STATUS_FILE_LOCK_CONFLICT); printf("Trying zero file read\n"); io.lockread.in.count = 0; status = smb_raw_read(cli->tree, &io); CHECK_STATUS(status, NT_STATUS_OK); smbcli_unlock(cli->tree, fnum, 1, 1); printf("Trying bad fnum\n"); io.lockread.in.file.fnum = fnum+1; status = smb_raw_read(cli->tree, &io); CHECK_STATUS(status, NT_STATUS_INVALID_HANDLE); io.lockread.in.file.fnum = fnum; smbcli_write(cli->tree, fnum, 0, test_data, 0, strlen(test_data)); printf("Trying small read\n"); io.lockread.in.file.fnum = fnum; io.lockread.in.offset = 0; io.lockread.in.remaining = 0; io.lockread.in.count = strlen(test_data); status = smb_raw_read(cli->tree, &io); CHECK_STATUS(status, NT_STATUS_LOCK_NOT_GRANTED); smbcli_unlock(cli->tree, fnum, 1, 0); status = smb_raw_read(cli->tree, &io); CHECK_STATUS(status, NT_STATUS_OK); CHECK_VALUE(io.lockread.out.nread, strlen(test_data)); if (memcmp(buf, test_data, strlen(test_data)) != 0) { ret = False; printf("incorrect data at %d!? (%s:%s)\n", __LINE__, test_data, buf); goto done; } printf("Trying short read\n"); io.lockread.in.offset = 1; io.lockread.in.count = strlen(test_data); status = smb_raw_read(cli->tree, &io); CHECK_STATUS(status, NT_STATUS_LOCK_NOT_GRANTED); smbcli_unlock(cli->tree, fnum, 0, strlen(test_data)); status = smb_raw_read(cli->tree, &io); CHECK_STATUS(status, NT_STATUS_OK); CHECK_VALUE(io.lockread.out.nread, strlen(test_data)-1); if (memcmp(buf, test_data+1, strlen(test_data)-1) != 0) { ret = False; printf("incorrect data at %d!? (%s:%s)\n", __LINE__, test_data+1, buf); goto done; } if (cli->transport->negotiate.capabilities & CAP_LARGE_FILES) { printf("Trying max offset\n"); io.lockread.in.offset = ~0; io.lockread.in.count = strlen(test_data); status = smb_raw_read(cli->tree, &io); CHECK_STATUS(status, NT_STATUS_OK); CHECK_VALUE(io.lockread.out.nread, 0); } setup_buffer(buf, seed, maxsize); smbcli_write(cli->tree, fnum, 0, buf, 0, maxsize); memset(buf, 0, maxsize); printf("Trying large read\n"); io.lockread.in.offset = 0; io.lockread.in.count = ~0; status = smb_raw_read(cli->tree, &io); CHECK_STATUS(status, NT_STATUS_LOCK_NOT_GRANTED); smbcli_unlock(cli->tree, fnum, 1, strlen(test_data)); status = smb_raw_read(cli->tree, &io); CHECK_STATUS(status, NT_STATUS_OK); CHECK_BUFFER(buf, seed, io.lockread.out.nread); smbcli_unlock(cli->tree, fnum, 0, 0xFFFF); printf("Trying locked region\n"); cli->session->pid++; if (NT_STATUS_IS_ERR(smbcli_lock(cli->tree, fnum, 103, 1, 0, WRITE_LOCK))) { printf("Failed to lock file at %d\n", __LINE__); ret = False; goto done; } cli->session->pid--; memset(buf, 0, maxsize); io.lockread.in.offset = 0; io.lockread.in.count = ~0; status = smb_raw_read(cli->tree, &io); CHECK_STATUS(status, NT_STATUS_FILE_LOCK_CONFLICT); done: smbcli_close(cli->tree, fnum); smbcli_deltree(cli->tree, BASEDIR); return ret; }
/* test writex ops */ static BOOL test_writex(struct smbcli_state *cli, TALLOC_CTX *mem_ctx) { union smb_write io; NTSTATUS status; BOOL ret = True; int fnum, i; uint8_t *buf; const int maxsize = 90000; const char *fname = BASEDIR "\\test.txt"; uint_t seed = time(NULL); union smb_fileinfo finfo; int max_bits=63; if (!lp_parm_bool(-1, "torture", "dangerous", False)) { max_bits=33; printf("dangerous not set - limiting range of test to 2^%d\n", max_bits); } buf = talloc_zero_size(mem_ctx, maxsize); if (!torture_setup_dir(cli, BASEDIR)) { return False; } printf("Testing RAW_WRITE_WRITEX\n"); io.generic.level = RAW_WRITE_WRITEX; fnum = smbcli_open(cli->tree, fname, O_RDWR|O_CREAT, DENY_NONE); if (fnum == -1) { printf("Failed to create %s - %s\n", fname, smbcli_errstr(cli->tree)); ret = False; goto done; } printf("Trying zero write\n"); io.writex.in.file.fnum = fnum; io.writex.in.offset = 0; io.writex.in.wmode = 0; io.writex.in.remaining = 0; io.writex.in.count = 0; io.writex.in.data = buf; status = smb_raw_write(cli->tree, &io); CHECK_STATUS(status, NT_STATUS_OK); CHECK_VALUE(io.writex.out.nwritten, 0); setup_buffer(buf, seed, maxsize); printf("Trying small write\n"); io.writex.in.count = 9; io.writex.in.offset = 4; io.writex.in.data = buf; status = smb_raw_write(cli->tree, &io); CHECK_STATUS(status, NT_STATUS_OK); CHECK_VALUE(io.writex.out.nwritten, io.writex.in.count); memset(buf, 0, maxsize); if (smbcli_read(cli->tree, fnum, buf, 0, 13) != 13) { printf("read failed at %s\n", __location__); ret = False; goto done; } CHECK_BUFFER(buf+4, seed, 9); CHECK_VALUE(IVAL(buf,0), 0); setup_buffer(buf, seed, maxsize); printf("Trying large write\n"); io.writex.in.count = 4000; io.writex.in.offset = 0; io.writex.in.data = buf; status = smb_raw_write(cli->tree, &io); CHECK_STATUS(status, NT_STATUS_OK); CHECK_VALUE(io.writex.out.nwritten, 4000); memset(buf, 0, maxsize); if (smbcli_read(cli->tree, fnum, buf, 0, 4000) != 4000) { printf("read failed at %s\n", __location__); ret = False; goto done; } CHECK_BUFFER(buf, seed, 4000); printf("Trying bad fnum\n"); io.writex.in.file.fnum = fnum+1; io.writex.in.count = 4000; io.writex.in.offset = 0; io.writex.in.data = buf; status = smb_raw_write(cli->tree, &io); CHECK_STATUS(status, NT_STATUS_INVALID_HANDLE); printf("Testing wmode\n"); io.writex.in.file.fnum = fnum; io.writex.in.count = 1; io.writex.in.offset = 0; io.writex.in.wmode = 1; io.writex.in.data = buf; status = smb_raw_write(cli->tree, &io); CHECK_STATUS(status, NT_STATUS_OK); CHECK_VALUE(io.writex.out.nwritten, io.writex.in.count); io.writex.in.wmode = 2; status = smb_raw_write(cli->tree, &io); CHECK_STATUS(status, NT_STATUS_OK); CHECK_VALUE(io.writex.out.nwritten, io.writex.in.count); printf("Trying locked region\n"); cli->session->pid++; if (NT_STATUS_IS_ERR(smbcli_lock(cli->tree, fnum, 3, 1, 0, WRITE_LOCK))) { printf("Failed to lock file at %s\n", __location__); ret = False; goto done; } cli->session->pid--; io.writex.in.wmode = 0; io.writex.in.count = 4; io.writex.in.offset = 0; status = smb_raw_write(cli->tree, &io); CHECK_STATUS(status, NT_STATUS_FILE_LOCK_CONFLICT); printf("Setting file as sparse\n"); status = torture_set_sparse(cli->tree, fnum); CHECK_STATUS(status, NT_STATUS_OK); if (!(cli->transport->negotiate.capabilities & CAP_LARGE_FILES)) { printf("skipping large file tests - CAP_LARGE_FILES not set\n"); goto done; } printf("Trying 2^32 offset\n"); setup_buffer(buf, seed, maxsize); io.writex.in.file.fnum = fnum; io.writex.in.count = 4000; io.writex.in.offset = 0xFFFFFFFF - 2000; io.writex.in.data = buf; status = smb_raw_write(cli->tree, &io); CHECK_STATUS(status, NT_STATUS_OK); CHECK_VALUE(io.writex.out.nwritten, 4000); CHECK_ALL_INFO(io.writex.in.count + (uint64_t)io.writex.in.offset, size); memset(buf, 0, maxsize); if (smbcli_read(cli->tree, fnum, buf, io.writex.in.offset, 4000) != 4000) { printf("read failed at %s\n", __location__); ret = False; goto done; } CHECK_BUFFER(buf, seed, 4000); for (i=33;i<max_bits;i++) { printf("Trying 2^%d offset\n", i); setup_buffer(buf, seed+1, maxsize); io.writex.in.file.fnum = fnum; io.writex.in.count = 4000; io.writex.in.offset = ((uint64_t)1) << i; io.writex.in.data = buf; status = smb_raw_write(cli->tree, &io); if (i>33 && NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) { break; } CHECK_STATUS(status, NT_STATUS_OK); CHECK_VALUE(io.writex.out.nwritten, 4000); CHECK_ALL_INFO(io.writex.in.count + (uint64_t)io.writex.in.offset, size); memset(buf, 0, maxsize); if (smbcli_read(cli->tree, fnum, buf, io.writex.in.offset, 4000) != 4000) { printf("read failed at %s\n", __location__); ret = False; goto done; } CHECK_BUFFER(buf, seed+1, 4000); } printf("limit is 2^%d\n", i); setup_buffer(buf, seed, maxsize); done: smbcli_close(cli->tree, fnum); smb_raw_exit(cli->session); smbcli_deltree(cli->tree, BASEDIR); return ret; }
/* test write ops */ static BOOL test_write(struct smbcli_state *cli, TALLOC_CTX *mem_ctx) { union smb_write io; NTSTATUS status; BOOL ret = True; int fnum; uint8_t *buf; const int maxsize = 90000; const char *fname = BASEDIR "\\test.txt"; uint_t seed = time(NULL); union smb_fileinfo finfo; buf = talloc_zero_size(mem_ctx, maxsize); if (!torture_setup_dir(cli, BASEDIR)) { return False; } printf("Testing RAW_WRITE_WRITE\n"); io.generic.level = RAW_WRITE_WRITE; fnum = smbcli_open(cli->tree, fname, O_RDWR|O_CREAT, DENY_NONE); if (fnum == -1) { printf("Failed to create %s - %s\n", fname, smbcli_errstr(cli->tree)); ret = False; goto done; } printf("Trying zero write\n"); io.write.in.file.fnum = fnum; io.write.in.count = 0; io.write.in.offset = 0; io.write.in.remaining = 0; io.write.in.data = buf; status = smb_raw_write(cli->tree, &io); CHECK_STATUS(status, NT_STATUS_OK); CHECK_VALUE(io.write.out.nwritten, 0); setup_buffer(buf, seed, maxsize); printf("Trying small write\n"); io.write.in.count = 9; io.write.in.offset = 4; io.write.in.data = buf; status = smb_raw_write(cli->tree, &io); CHECK_STATUS(status, NT_STATUS_OK); CHECK_VALUE(io.write.out.nwritten, io.write.in.count); memset(buf, 0, maxsize); if (smbcli_read(cli->tree, fnum, buf, 0, 13) != 13) { printf("read failed at %s\n", __location__); ret = False; goto done; } CHECK_BUFFER(buf+4, seed, 9); CHECK_VALUE(IVAL(buf,0), 0); setup_buffer(buf, seed, maxsize); printf("Trying large write\n"); io.write.in.count = 4000; io.write.in.offset = 0; io.write.in.data = buf; status = smb_raw_write(cli->tree, &io); CHECK_STATUS(status, NT_STATUS_OK); CHECK_VALUE(io.write.out.nwritten, 4000); memset(buf, 0, maxsize); if (smbcli_read(cli->tree, fnum, buf, 0, 4000) != 4000) { printf("read failed at %s\n", __location__); ret = False; goto done; } CHECK_BUFFER(buf, seed, 4000); printf("Trying bad fnum\n"); io.write.in.file.fnum = fnum+1; io.write.in.count = 4000; io.write.in.offset = 0; io.write.in.data = buf; status = smb_raw_write(cli->tree, &io); CHECK_STATUS(status, NT_STATUS_INVALID_HANDLE); printf("Setting file as sparse\n"); status = torture_set_sparse(cli->tree, fnum); CHECK_STATUS(status, NT_STATUS_OK); if (!(cli->transport->negotiate.capabilities & CAP_LARGE_FILES)) { printf("skipping large file tests - CAP_LARGE_FILES not set\n"); goto done; } if (!(cli->transport->negotiate.capabilities & CAP_LARGE_FILES)) { printf("skipping large file tests - CAP_LARGE_FILES not set\n"); goto done; } printf("Trying 2^32 offset\n"); setup_buffer(buf, seed, maxsize); io.write.in.file.fnum = fnum; io.write.in.count = 4000; io.write.in.offset = 0xFFFFFFFF - 2000; io.write.in.data = buf; status = smb_raw_write(cli->tree, &io); CHECK_STATUS(status, NT_STATUS_OK); CHECK_VALUE(io.write.out.nwritten, 4000); CHECK_ALL_INFO(io.write.in.count + (uint64_t)io.write.in.offset, size); memset(buf, 0, maxsize); if (smbcli_read(cli->tree, fnum, buf, io.write.in.offset, 4000) != 4000) { printf("read failed at %s\n", __location__); ret = False; goto done; } CHECK_BUFFER(buf, seed, 4000); done: smbcli_close(cli->tree, fnum); smb_raw_exit(cli->session); smbcli_deltree(cli->tree, BASEDIR); return ret; }
int rds_cmd_parse(struct data_node *p_node) { int loop = 0; int i,j = 0; int offset = 0; size_t mlen = 0; char *p_new = NULL; char *p_old = NULL; /* parse cmd */ char *data = p_node->recv.buf_addr; struct redis_parser *p_parser = &p_node->redis_info.rp; struct redis_status *p_status = &p_node->redis_info.rs; x_printf(D, "%s\n", data); if (data[0] == '*'){ // 1. read the arg count: if (p_parser->kvs == 0) { p_new = p_old = &data[1]; CHECK_BUFFER(p_new, 0); p_parser->kvs = atoi( p_old ); p_parser->doptr = p_new - data; rds_reset_status(p_node); } // 2. read the request name if (p_parser->cmd == 0){ if (data[ p_parser->doptr ] != '$'){ return X_PARSE_ERROR; } p_new = p_old = &data[ p_parser->doptr + 1]; CHECK_BUFFER(p_new, 0); mlen = atoi( p_old ); p_old = p_new; CHECK_BUFFER(p_new, mlen); for (i = 0; i < mlen; i++){ if ( *(p_old + i) > 'Z' ){ *(p_old + i) -= 32;/* 'A' - 'a' */ } p_parser->cmd = p_parser->cmd * 26 + ( *(p_old + i) - 'A' );/* A~Z is 26 numbers */ } p_parser->doptr = p_new - data; } x_printf(D, "%d\n", p_parser->cmd); // 3. read a arg switch (p_parser->cmd){ case CMD_SET: PARSE_LEN(p_parser->klen); PARSE_MEMBER_AND_STORE(p_parser->key, p_parser->klen, p_status->keys, p_status->key_offset, p_status->klen_array); PARSE_LEN(p_parser->vlen); PARSE_MEMBER_AND_STORE(p_parser->val, p_parser->vlen, p_status->vals, p_status->val_offset, p_status->vlen_array); p_status->order = SET_FUNC_ORDER; return X_DATA_IS_ALL; case CMD_LPUSHX: PARSE_LEN(p_parser->klen); PARSE_MEMBER_AND_STORE(p_parser->key, p_parser->klen, p_status->keys, p_status->key_offset, p_status->klen_array); PARSE_LEN(p_parser->vlen); PARSE_MEMBER_AND_STORE(p_parser->val, p_parser->vlen, p_status->vals, p_status->val_offset, p_status->vlen_array); p_status->order = LPUSHX_FUNC_ORDER; return X_DATA_IS_ALL; case CMD_RPUSHX: PARSE_LEN(p_parser->klen); PARSE_MEMBER_AND_STORE(p_parser->key, p_parser->klen, p_status->keys, p_status->key_offset, p_status->klen_array); PARSE_LEN(p_parser->vlen); PARSE_MEMBER_AND_STORE(p_parser->val, p_parser->vlen, p_status->vals, p_status->val_offset, p_status->vlen_array); p_status->order = RPUSHX_FUNC_ORDER; return X_DATA_IS_ALL; case CMD_DEL: PARSE_LEN(p_parser->klen); PARSE_MEMBER_AND_STORE(p_parser->key, p_parser->klen, p_status->keys, p_status->key_offset, p_status->klen_array); //p_status->type = BIT8_TASK_TYPE_ALONE; //p_status->func = NULL;//FIXME return X_DATA_IS_ALL; case CMD_MSET:/* use one thread to write, otherwise add a mutex lock */ loop = (p_parser->kvs - 1) / 2; for (j = 0; j < loop; j++){ PARSE_LEN(p_parser->klen); PARSE_MEMBER_AND_STORE(p_parser->key, p_parser->klen, p_status->keys, p_status->key_offset, p_status->klen_array); PARSE_LEN(p_parser->vlen); PARSE_MEMBER_AND_STORE(p_parser->val, p_parser->vlen, p_status->vals, p_status->val_offset, p_status->vlen_array); p_parser->kvs -= 2; p_parser->klen = 0; p_parser->key = 0; p_parser->vlen = 0; p_parser->val = 0; } //p_status->type = BIT8_TASK_TYPE_ALONE; //p_status->func = NULL;//FIXME return X_DATA_IS_ALL; case CMD_HSET: PARSE_LEN(p_parser->klen); PARSE_MEMBER_AND_STORE(p_parser->key, p_parser->klen, p_status->keys, p_status->key_offset, p_status->klen_array); PARSE_LEN(p_parser->flen); PARSE_MEMBER_AND_STORE(p_parser->fld, p_parser->flen, p_status->flds, p_status->fld_offset, p_status->flen_array); PARSE_LEN(p_parser->vlen); PARSE_MEMBER_AND_STORE(p_parser->val, p_parser->vlen, p_status->vals, p_status->val_offset, p_status->vlen_array); p_status->order = HSET_FUNC_ORDER; return X_DATA_IS_ALL; case CMD_GET: PARSE_LEN(p_parser->klen); PARSE_MEMBER_AND_STORE(p_parser->key, p_parser->klen, p_status->keys, p_status->key_offset, p_status->klen_array); //p_status->type = BIT8_TASK_TYPE_ALONE; //p_status->func = NULL;//FIXME return X_DATA_IS_ALL; //case CMD_MGET: case CMD_HMGET://FIXME key switch filed PARSE_LEN(p_parser->flen); PARSE_MEMBER_AND_STORE(p_parser->fld, p_parser->flen, p_status->flds, p_status->fld_offset, p_status->flen_array); loop = p_parser->kvs - 2; for (j = 0; j < loop; j++){ PARSE_LEN(p_parser->klen); PARSE_MEMBER_AND_STORE(p_parser->key, p_parser->klen, p_status->keys, p_status->key_offset, p_status->klen_array); p_parser->kvs --; p_parser->klen = 0; p_parser->key = 0; } p_status->order = HMGET_FUNC_ORDER; return X_DATA_IS_ALL; case CMD_HGETALL: PARSE_LEN(p_parser->klen); PARSE_MEMBER_AND_STORE(p_parser->key, p_parser->klen, p_status->keys, p_status->key_offset, p_status->klen_array); p_status->order = HGETALL_FUNC_ORDER; //p_status->type = BIT8_TASK_TYPE_ALONE; //p_status->func = NULL;//FIXME return X_DATA_IS_ALL; case CMD_LRANGE: /* look as start key */ PARSE_LEN(p_parser->klen); PARSE_MEMBER_AND_STORE(p_parser->key, p_parser->klen, p_status->keys, p_status->key_offset, p_status->klen_array); /* look as end key */ PARSE_LEN(p_parser->vlen); PARSE_MEMBER_AND_STORE(p_parser->val, p_parser->vlen, p_status->vals, p_status->val_offset, p_status->vlen_array); //p_status->type = BIT8_TASK_TYPE_ALONE; //p_status->func = NULL;//FIXME return X_DATA_IS_ALL; case CMD_QUIT: return X_REQUEST_QUIT; default: return X_REQUEST_ERROR; } } else if (data[0] == '$'){ #if 0 // 1. read the request name if (p_parser->cmd == 0){ p_new = p_old = &data[1]; CHECK_BUFFER(p_new, 0); mlen = atoi( p_old ); p_old = p_new; CHECK_BUFFER(p_new, mlen); for (i = 0; i < mlen; i++){ p_parser->cmd = p_parser->cmd * 26 + ( *(p_old + i) - 'A' );/* A~Z is 26 numbers */ } p_parser->doptr = p_new - data; } x_printf(D, "%d\n", p_parser->cmd); // 2. read a arg switch (p_parser->cmd){ case CMD_QUIT: return CLIENT_QUIT; default: x_printf(D, "-----------------------------------------------------\n"); return -1; } //TODO #endif return X_REQUEST_ERROR; }else{ return X_PARSE_ERROR; } return X_DATA_IS_ALL; }