Skip to content

Commit

Permalink
Added dataset creation functionality
Browse files Browse the repository at this point in the history
Signed-off-by: Charlie Caron <[email protected]>
  • Loading branch information
Charlie Caron committed Jul 30, 2019
1 parent e85b841 commit 2a2cbc5
Show file tree
Hide file tree
Showing 4 changed files with 474 additions and 0 deletions.
353 changes: 353 additions & 0 deletions c/datasetjson.c
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
#include "json.h"
#include "bpxnet.h"
#include "unixfile.h"
#include "errno.h"
#ifdef __ZOWE_OS_ZOS
#include "zos.h"
#endif
Expand Down Expand Up @@ -53,6 +54,10 @@ static int defaultVSAMCSIFieldCount = 4;

static char getRecordLengthType(char *dscb);
static int getMaxRecordLength(char *dscb);
static int updateInputParmsProperty(JsonObject *object, int *configsCount, DynallocNewTextUnit *textUnit);
static void setTextUnitString(int size, char* data, int *configsCount, int key, DynallocNewTextUnit *textUnit);
static void setTextUnitCharOrInt(int size, int data, int *configsCount, int key, DynallocNewTextUnit *textUnit);
static void setTextUnitBool(int *configsCount, int key, DynallocNewTextUnit *textUnit);
static void respondWithNonVSAMDataset(HttpResponse* response, char* absolutePath, int jsonMode);
static void respondWithVSAMDataset(HttpResponse* response, char* absolutePath, hashtable *acbTable, int jsonMode);
static void updateNonVSAMDataset(HttpResponse* response, char* absolutePath, int jsonMode);
Expand Down Expand Up @@ -1719,6 +1724,354 @@ void respondWithHLQNames(HttpResponse *response, MetadataQueryCache *metadataQue
#endif /* __ZOWE_OS_ZOS */
}

static int updateInputParmsProperty(JsonObject *object, int *configsCount, DynallocNewTextUnit *textUnit) {
Json* value = jsonObjectGetPropertyValue(object, "dsorg");
if (jsonIsString(value)){
if (!strcmp(value->data.string, "PS")) {
setTextUnitCharOrInt(sizeof(short), DALDSORG_PS, configsCount, DALDSORG, textUnit);
}
else if (!strcmp(value->data.string, "PO")) {
setTextUnitCharOrInt(sizeof(short), DALDSORG_PO, configsCount, DALDSORG, textUnit);
}
}

errno = 0;
value = jsonObjectGetPropertyValue(object, "blksz");
if (jsonIsString(value)){
long toi = strtol(value->data.string, NULL, 0);
if(errno != ERANGE){
if (toi <= 0x7FF8 && toi >= 0) { //<-- If DASD, if tape, it can be 80000000
setTextUnitCharOrInt(sizeof(short), toi, configsCount, DALBLKSZ, textUnit);
}
else if (toi <= 0x80000000){
setTextUnitCharOrInt(sizeof(long long), toi, configsCount, DALBLKSZ, textUnit);
}
}
}

errno = 0;
value = jsonObjectGetPropertyValue(object, "lrecl");
if (jsonIsString(value)){
long toi = strtol(value->data.string, NULL, 0);
if (errno != ERANGE){
if (toi == 0x8000) {
setTextUnitCharOrInt(sizeof(short), toi, configsCount, DALLRECL, textUnit);
}
else if (toi <= 0x7FF8 && toi >= 0) {
setTextUnitCharOrInt(sizeof(short), toi, configsCount, DALLRECL, textUnit);
}
}
}
value = jsonObjectGetPropertyValue(object, "volser");
if (jsonIsString(value)){
if (strlen(value->data.string) <= VOLSER_SIZE){
setTextUnitString(VOLSER_SIZE, &(value->data.string)[0], configsCount, DALVLSER, textUnit);
}
}

value = jsonObjectGetPropertyValue(object, "recfm");
if (jsonIsString(value)){
int setRECFM = 0;
if (indexOf(value->data.string, strlen(value->data.string), 'A', 0) != -1){
setRECFM = setRECFM | DALRECFM_A;
}
if (indexOf(value->data.string, strlen(value->data.string), 'B', 0) != -1){
setRECFM = setRECFM | DALRECFM_B;
}
if (indexOf(value->data.string, strlen(value->data.string), 'V', 0) != -1){
setRECFM = setRECFM | DALRECFM_V;
}
if (indexOf(value->data.string, strlen(value->data.string), 'F', 0) != -1){
setRECFM = setRECFM | DALRECFM_F;
}
if (indexOf(value->data.string, strlen(value->data.string), 'U', 0) != -1){
setRECFM = setRECFM | DALRECFM_U;
}
setTextUnitCharOrInt(sizeof(char), setRECFM, configsCount, DALRECFM, textUnit);
}

errno = 0;
value = jsonObjectGetPropertyValue(object, "prime");
if (jsonIsString(value)){
long toi = strtol(value->data.string, NULL, 0);
if (toi <= 0xFFFFFF || toi >= 0) {
if (errno != ERANGE){
setTextUnitCharOrInt(INT24_SIZE, toi, configsCount, DALPRIME, textUnit);
}
}
}

errno = 0;
value = jsonObjectGetPropertyValue(object, "second");
if (jsonIsString(value)){
long toi = strtol(value->data.string, NULL, 0);
if (toi <= 0xFFFFFF || toi >= 0) {
if (errno != ERANGE){
setTextUnitCharOrInt(INT24_SIZE, toi, configsCount, DALSECND, textUnit);
}
}
}

value = jsonObjectGetPropertyValue(object, "space");
if (jsonIsString(value)){
if (!strcmp(value->data.string, "cyl")){
setTextUnitBool(configsCount, DALCYL, textUnit);
}
if (!strcmp(value->data.string, "trk")){
setTextUnitBool(configsCount, DALCYL, textUnit);
}
}

errno = 0;
value = jsonObjectGetPropertyValue(object, "blkln");
if (jsonIsString(value)){
long toi = strtol(value->data.string, NULL, 0);
if (toi <= 0xFFFF || toi >= 0) {
if (errno != ERANGE){
setTextUnitCharOrInt(INT24_SIZE, toi, configsCount, DALBLKLN, textUnit);
}
}
}

value = jsonObjectGetPropertyValue(object, "status");
if (jsonIsString(value)){
if (!strcmp(value->data.string, "OLD")){
setTextUnitCharOrInt(sizeof(char), DISP_OLD, configsCount, DALSTATS, textUnit);
}
else if (!strcmp(value->data.string, "MOD")){
setTextUnitCharOrInt(sizeof(char), DISP_MOD, configsCount, DALSTATS, textUnit);
}
else if (!strcmp(value->data.string, "SHARE")){
setTextUnitCharOrInt(sizeof(char), DISP_SHARE, configsCount, DALSTATS, textUnit);
}
else {
setTextUnitCharOrInt(sizeof(char), DISP_NEW, configsCount, DALSTATS, textUnit);
}
}
else {
setTextUnitCharOrInt(sizeof(char), DISP_NEW, configsCount, DALSTATS, textUnit);
}

value = jsonObjectGetPropertyValue(object, "ndisp");
if (jsonIsString(value)){
if (!strcmp(value->data.string, "UNCATLG")){
setTextUnitCharOrInt(sizeof(char), DISP_UNCATLG, configsCount, DALNDISP, textUnit);
}
else if (!strcmp(value->data.string, "DELETE")){
setTextUnitCharOrInt(sizeof(char), DISP_DELETE, configsCount, DALNDISP, textUnit);
}
else if (!strcmp(value->data.string, "KEEP")){
setTextUnitCharOrInt(sizeof(char), DISP_KEEP, configsCount, DALNDISP, textUnit);
}
else {
setTextUnitCharOrInt(sizeof(char), DISP_CATLG, configsCount, DALNDISP, textUnit);
}
}
else {
setTextUnitCharOrInt(sizeof(char), DISP_CATLG, configsCount, DALNDISP, textUnit);
}

value = jsonObjectGetPropertyValue(object, "unit");
if (jsonIsString(value)){
setTextUnitString(strlen(value->data.string), &(value->data.string)[0], configsCount, DALUNIT, textUnit);
}

value = jsonObjectGetPropertyValue(object, "sysout");
if (jsonIsString(value)){
if (!strcmp(value->data.string, "default")){
for(int i = 0; i < *configsCount; i++) {
if (textUnit[i].key == DALSTATS || textUnit[i].key == DALNDISP) {
textUnit[i].type = TEXT_UNIT_NULL;
}
}
setTextUnitBool(configsCount, DALSYSOU, textUnit);
}
else if (isalnum(value->data.string[0])) {
for(int i = 0; i < *configsCount; i++) {
if (textUnit[i].key == DALSTATS || textUnit[i].key == DALNDISP) {
textUnit[i].type == TEXT_UNIT_NULL;
}
}
setTextUnitCharOrInt(1, value->data.string[0], configsCount, DALSYSOU, textUnit);
}
}

value = jsonObjectGetPropertyValue(object, "spgnm");
if (jsonIsString(value)){
if (strlen(value->data.string) <= CLASS_WRITER_SIZE){
setTextUnitString(strlen(value->data.string), &(value->data.string)[0], configsCount, DALSPGNM, textUnit);
}
}

value = jsonObjectGetPropertyValue(object, "close");
if (jsonIsString(value)){
if (!strcmp(value->data.string, "true")){
setTextUnitBool(configsCount, DALCLOSE, textUnit);
}
}

value = jsonObjectGetPropertyValue(object, "dummy");
if (jsonIsString(value)){
if (!strcmp(value->data.string, "true")){
setTextUnitBool(configsCount, DALDUMMY, textUnit);
}
}

value = jsonObjectGetPropertyValue(object, "dcbdd");
if (jsonIsString(value)){
if (strlen(value->data.string) <= DD_NAME_LEN){
setTextUnitString(DD_NAME_LEN, &(value->data.string)[0], configsCount, DALDCBDD, textUnit);
}
}

value = jsonObjectGetPropertyValue(object, "retdd");
if (jsonIsString(value)){
if (strlen(value->data.string) <= DD_NAME_LEN){
setTextUnitString(DD_NAME_LEN, &(value->data.string)[0], configsCount, DALRTDDN, textUnit);
}
}

value = jsonObjectGetPropertyValue(object, "spin");
if (jsonIsString(value)){
if (!strcmp(value->data.string, "UNALLOC")){
setTextUnitCharOrInt(1, SPIN_UNALLOC, configsCount, DALSPIN, textUnit);
}
else if (!strcmp(value->data.string, "ENDJOB")){
setTextUnitCharOrInt(1, SPIN_ENDJOB, configsCount, DALSPIN, textUnit);
}
}

value = jsonObjectGetPropertyValue(object, "strcls");
if (jsonIsString(value)){
if (strlen(value->data.string) <= CLASS_WRITER_SIZE){
setTextUnitString(8, &(value->data.string)[0], configsCount, DALSTCL, textUnit);
}
}

value = jsonObjectGetPropertyValue(object, "mngcls");
if (jsonIsString(value)){
if (strlen(value->data.string) <= CLASS_WRITER_SIZE){
setTextUnitString(CLASS_WRITER_SIZE, &(value->data.string)[0], configsCount, DALMGCL, textUnit);
}
}

value = jsonObjectGetPropertyValue(object, "datacls");
if (jsonIsString(value)){
if (strlen(value->data.string) <= CLASS_WRITER_SIZE){
setTextUnitString(CLASS_WRITER_SIZE, &(value->data.string)[0], configsCount, DALDACL, textUnit);
}
}
}

static void setTextUnitString(int size, char* data, int *configsCount, int key, DynallocNewTextUnit *textUnit) {
textUnit[*configsCount].size = size;
textUnit[*configsCount].type = TEXT_UNIT_STRING;
textUnit[*configsCount].key = key;
textUnit[*configsCount].data.string = data;
(*configsCount)++;
}

static void setTextUnitCharOrInt(int size, int data, int *configsCount, int key, DynallocNewTextUnit *textUnit) {
textUnit[*configsCount].size = size;
textUnit[*configsCount].type = TEXT_UNIT_CHARINT;
textUnit[*configsCount].key = key;
textUnit[*configsCount].data.number = data;
(*configsCount)++;
}

static void setTextUnitBool(int *configsCount, int key, DynallocNewTextUnit *textUnit) {
textUnit[*configsCount].type = TEXT_UNIT_BOOLEAN;
textUnit[*configsCount].key = key;
(*configsCount)++;
}

void newDataset(HttpResponse* response, char* datasetName, int jsonMode){
#ifdef __ZOWE_OS_ZOS

DatasetName dsn = {0};
memset(dsn.value, ' ', DATASET_NAME_LEN);

int lParenIndex = indexOf(datasetName, strlen(datasetName),'(',0);

//String parsing operation, gets rid of of 3 initial unnecessary characters-> //'
if (lParenIndex > 0){
memcpy(dsn.value,datasetName+3,lParenIndex-3);
}
//String parsing operation, gets rid of of 3 initial unnecessary characters-> //'
else{
memcpy(dsn.value,datasetName+3,strlen(datasetName)-4);
}

int configsCount = 0;
DynallocNewTextUnit textUnits[TOTAL_TEXT_UNITS];
setTextUnitString(DATASET_NAME_LEN, &dsn.value[0], &configsCount, DALDSNAM, &textUnits[0]);
setTextUnitString(DD_NAME_LEN, "MVD00000", &configsCount, DALDDNAM, &textUnits[0]);

if (jsonMode != TRUE) { /*TODO add support for updating files with raw bytes instead of JSON*/
respondWithError(response, HTTP_STATUS_BAD_REQUEST,"Cannot update file without JSON formatted record request");
return;
}

HttpRequest *request = response->request;

FileInfo info;

char *contentBody = request->contentBody;
int bodyLength = strlen(contentBody);

char *convertedBody = safeMalloc(bodyLength*4,"writeDatasetConvert");
int conversionBufferLength = bodyLength*4;
int translationLength;
int outCCSID = NATIVE_CODEPAGE;
int reasonCode;

int returnCode = convertCharset(contentBody,
bodyLength,
CCSID_UTF_8,
CHARSET_OUTPUT_USE_BUFFER,
&convertedBody,
conversionBufferLength,
outCCSID,
NULL,
&translationLength,
&reasonCode);

if(returnCode == 0) {

ShortLivedHeap *slh = makeShortLivedHeap(0x10000,0x10);
char errorBuffer[2048];
Json *json = jsonParseUnterminatedString(slh,
convertedBody, translationLength,
errorBuffer, sizeof(errorBuffer));
if (json) {
if (jsonIsObject(json)){
JsonObject * jsonObject = jsonAsObject(json);
updateInputParmsProperty(jsonObject, &configsCount, &textUnits[0]);
}
}
}

returnCode = dynallocNewDataset(&reasonCode, &textUnits[0], configsCount);
int ddNumber = 1;
char buffer[DD_NAME_LEN + 1];
while (reasonCode==0x4100000 && ddNumber < 100000) {
sprintf(buffer, "MVD%05d", ddNumber);
int ddconfig = 1;
setTextUnitString(DD_NAME_LEN, buffer, &ddconfig, DALDDNAM, &textUnits[0]);
returnCode = dynallocNewDataset(&reasonCode, &textUnits[0], configsCount);
ddNumber++;
}
if (returnCode) {
printf("Dynalloc RC = %d, reasonCode = %x\n", returnCode, reasonCode);
respondWithError(response, HTTP_STATUS_INTERNAL_SERVER_ERROR, "Unable to allocate a DD for ACB");
return;
}
else {
printf("Dynalloc RC = %d, reasonCode = %x\n", returnCode, reasonCode);
response200WithMessage(response, "Successfully created dataset");
}
#endif
}

#endif /* not METTLE - the whole module */

Expand Down
Loading

0 comments on commit 2a2cbc5

Please sign in to comment.