Example #1
0
static json_t *SaveStaticTiles(Mission *m)
{
	// Create a text buffer for CSV
	// The buffer will contain n*5 chars (tiles, allow 5 chars each),
	// and n - 1 commas, so 6n total
	const int size = (int)m->u.Static.Tiles.size;
	if (size == 0)
	{
		return json_new_string("");
	}
	char *bigbuf;
	CCALLOC(bigbuf, size * 6);
	char *pBuf = bigbuf;
	CASSERT(pBuf != NULL, "memory error");
	for (int i = 0; i < size; i++)
	{
		char buf[32];
		sprintf(buf, "%d", *(unsigned short *)CArrayGet(
			&m->u.Static.Tiles, i));
		strcpy(pBuf, buf);
		pBuf += strlen(buf);
		if (i < size - 1)
		{
			*pBuf = ',';
			pBuf++;
		}
	}
	json_t *node = json_new_string(bigbuf);
	CFREE(bigbuf);
	return node;
}
/*
** Very incomplete/incorrect impl of /json/artifact/TICKET_ID.
*/
cson_value * json_artifact_ticket( cson_object * zParent, int rid ){
  cson_object * pay = NULL;
  Manifest *pTktChng = NULL;
  static cson_value * eventTypeLabel = NULL;
  if(! g.perm.RdTkt ){
    g.json.resultCode = FSL_JSON_E_DENIED;
    return NULL;
  }
  if(!eventTypeLabel){
    eventTypeLabel = json_new_string("ticket");
    json_gc_add("$EVENT_TYPE_LABEL(ticket)", eventTypeLabel);
  }

  pTktChng = manifest_get(rid, CFTYPE_TICKET);
  if( pTktChng==0 ){
    g.json.resultCode = FSL_JSON_E_MANIFEST_READ_FAILED;
    return NULL;
  }
  pay = cson_new_object();
  cson_object_set(pay, "eventType", eventTypeLabel );
  cson_object_set(pay, "uuid", json_new_string(pTktChng->zTicketUuid));
  cson_object_set(pay, "user", json_new_string(pTktChng->zUser));
  cson_object_set(pay, "timestamp", json_julian_to_timestamp(pTktChng->rDate));
  manifest_destroy(pTktChng);
  return cson_object_value(pay);
}
Example #3
0
static void AddQuickPlayConfigNode(QuickPlayConfig *config, json_t *root)
{
	json_t *subConfig = json_new_object();
	json_insert_pair_into_object(
		subConfig, "MapSize", json_new_string(QuickPlayQuantityStr(config->MapSize)));
	json_insert_pair_into_object(
		subConfig, "WallCount", json_new_string(QuickPlayQuantityStr(config->WallCount)));
	json_insert_pair_into_object(
		subConfig, "WallLength", json_new_string(QuickPlayQuantityStr(config->WallLength)));
	json_insert_pair_into_object(
		subConfig, "RoomCount", json_new_string(QuickPlayQuantityStr(config->RoomCount)));
	json_insert_pair_into_object(
		subConfig, "SquareCount", json_new_string(QuickPlayQuantityStr(config->SquareCount)));
	json_insert_pair_into_object(
		subConfig, "EnemyCount", json_new_string(QuickPlayQuantityStr(config->EnemyCount)));
	json_insert_pair_into_object(
		subConfig, "EnemySpeed", json_new_string(QuickPlayQuantityStr(config->EnemySpeed)));
	json_insert_pair_into_object(
		subConfig, "EnemyHealth", json_new_string(QuickPlayQuantityStr(config->EnemyHealth)));
	json_insert_pair_into_object(
		subConfig, "EnemiesWithExplosives", json_new_bool(config->EnemiesWithExplosives));
	json_insert_pair_into_object(
		subConfig, "ItemCount", json_new_string(QuickPlayQuantityStr(config->ItemCount)));
	json_insert_pair_into_object(root, "QuickPlay", subConfig);
}
Example #4
0
void AddStringPair(json_t *parent, const char *name, const char *s)
{
	if (!s)
	{
		json_insert_pair_into_object(parent, name, json_new_string(""));
	}
	else
	{
		json_insert_pair_into_object(
			parent, name, json_new_string(json_escape(s)));
	}
}
Example #5
0
/*
** Implementation of the /json/diff page.
**
** Arguments:
**
** v1=1st version to diff
** v2=2nd version to diff
**
** Can come from GET, POST.payload, CLI -v1/-v2 or as positional
** parameters following the command name (in HTTP and CLI modes).
**
*/
cson_value * json_page_diff(){
  cson_object * pay = NULL;
  cson_value * v = NULL;
  char const * zFrom;
  char const * zTo;
  int nContext = 0;
  char doSBS;
  char doHtml;
  if(!g.perm.Read){
    json_set_err(FSL_JSON_E_DENIED,
                 "Requires 'o' permissions.");
    return NULL;
  }
  zFrom = json_find_option_cstr("v1",NULL,NULL);
  if(!zFrom){
    zFrom = json_command_arg(2);
  }
  if(!zFrom){
    json_set_err(FSL_JSON_E_MISSING_ARGS,
                 "Required 'v1' parameter is missing.");
    return NULL;
  }
  zTo = json_find_option_cstr("v2",NULL,NULL);
  if(!zTo){
    zTo = json_command_arg(3);
  }
  if(!zTo){
    json_set_err(FSL_JSON_E_MISSING_ARGS,
                 "Required 'v2' parameter is missing.");
    return NULL;
  }
  nContext = json_find_option_int("context",NULL,"c",5);
  doSBS = json_find_option_bool("sbs",NULL,"y",0);
  doHtml = json_find_option_bool("html",NULL,"h",0);
  v = json_generate_diff(zFrom, zTo, nContext, doSBS, doHtml);
  if(!v){
    if(!g.json.resultCode){
      json_set_err(FSL_JSON_E_UNKNOWN,
                   "Generating diff failed for unknown reason.");
    }
    return NULL;
  }
  pay = cson_new_object();
  cson_object_set(pay, "from", json_new_string(zFrom));
  cson_object_set(pay, "to", json_new_string(zTo));
  cson_object_set(pay, "diff", v);
  v = 0;
  
  return pay ? cson_object_value(pay) : NULL;
}
Example #6
0
void ScriptDialog::saveJson()
{
	json_t *root = json_new_object();
	json_t *t;
	t = json_new_number((const char*)m_id.toLatin1());
	json_insert_pair_into_object(root, "id", t);

	t = json_new_string((const char*)m_title.toLocal8Bit());
	json_insert_pair_into_object(root, "title", t);

	t = json_new_string((const char*)m_url.toLocal8Bit());
	json_insert_pair_into_object(root, "url", t);

	json_t *seqNode = json_new_array();
	for(int i=0, len=m_stepSeq.size(); i<len; ++i){
		QString s = m_stepSeq.at(i);
		json_t *v = json_new_string((const char*)s.toLocal8Bit());
		json_insert_child(seqNode, v);
	}

	json_t *stepsNode = json_new_object();
	json_insert_pair_into_object(stepsNode, "seq", seqNode);
	QMapIterator<QString, QString> iter(m_steps);
	while(iter.hasNext()){
		iter.next();
		if(iter.value().isEmpty())continue;

		QByteArray ba_k = iter.key().toLocal8Bit();
		const char *k = (const char*)ba_k;
		QByteArray ba_v = iter.value().toLocal8Bit();
		char *v = ba_v.data();

		QByteArray ba_t = m_stepTests.value(iter.key()).toLocal8Bit();
		char *t = ba_t.data();
		
		v = json_escape(v);
		t = json_escape(t);
		json_t *vn = json_new_string( v );
		json_t *tn = json_new_string( t );

		json_t *step = json_new_object();
		json_insert_pair_into_object(step, "test", tn);
		json_insert_pair_into_object(step, "script", vn);
		json_insert_pair_into_object(stepsNode, k, step);
	}
	json_insert_pair_into_object(root, "steps", stepsNode);

	BatDownUtils::writeJsonToFile(root, m_fn);
}
Example #7
0
static json_t *SaveCharacters(CharacterStore *s)
{
	json_t *charNode = json_new_array();
	int i;
	for (i = 0; i < (int)s->OtherChars.size; i++)
	{
		json_t *node = json_new_object();
		Character *c = CArrayGet(&s->OtherChars, i);
		AddIntPair(node, "face", c->looks.Face);
		AddIntPair(node, "skin", c->looks.Skin);
		AddIntPair(node, "arm", c->looks.Arm);
		AddIntPair(node, "body", c->looks.Body);
		AddIntPair(node, "leg", c->looks.Leg);
		AddIntPair(node, "hair", c->looks.Hair);
		AddIntPair(node, "speed", c->speed);
		json_insert_pair_into_object(
			node, "Gun", json_new_string(c->Gun->name));
		AddIntPair(node, "maxHealth", c->maxHealth);
		AddIntPair(node, "flags", c->flags);
		AddIntPair(node, "probabilityToMove", c->bot->probabilityToMove);
		AddIntPair(node, "probabilityToTrack", c->bot->probabilityToTrack);
		AddIntPair(node, "probabilityToShoot", c->bot->probabilityToShoot);
		AddIntPair(node, "actionDelay", c->bot->actionDelay);
		json_insert_child(charNode, node);
	}
	return charNode;
}
Example #8
0
/*
** If any files are associated with the given rid, a JSON array
** containing information about them is returned (and is owned by the
** caller). If no files are associated with it then NULL is returned.
**
** flags may optionally be a bitmask of json_get_changed_files flags,
** or 0 for defaults.
*/
cson_value * json_get_changed_files(int rid, int flags){
  cson_value * rowsV = NULL;
  cson_array * rows = NULL;
  Stmt q = empty_Stmt;
  db_prepare(&q,
           "SELECT (pid==0) AS isnew,"
           "       (fid==0) AS isdel,"
           "       (SELECT name FROM filename WHERE fnid=mlink.fnid) AS name,"
           "       blob.uuid as uuid,"
           "       (SELECT uuid FROM blob WHERE rid=pid) as parent,"
           "       blob.size as size"
           "  FROM mlink, blob"
           " WHERE mid=%d AND pid!=fid"
           " AND blob.rid=fid AND NOT mlink.isaux"
           " ORDER BY name /*sort*/",
             rid
             );
  while( (SQLITE_ROW == db_step(&q)) ){
    cson_value * rowV = cson_value_new_object();
    cson_object * row = cson_value_get_object(rowV);
    int const isNew = db_column_int(&q,0);
    int const isDel = db_column_int(&q,1);
    char * zDownload = NULL;
    if(!rowsV){
      rowsV = cson_value_new_array();
      rows = cson_value_get_array(rowsV);
    }
    cson_array_append( rows, rowV );
    cson_object_set(row, "name", json_new_string(db_column_text(&q,2)));
    cson_object_set(row, "uuid", json_new_string(db_column_text(&q,3)));
    if(!isNew && (flags & json_get_changed_files_ELIDE_PARENT)){
      cson_object_set(row, "parent", json_new_string(db_column_text(&q,4)));
    }
    cson_object_set(row, "size", json_new_int(db_column_int(&q,5)));

    cson_object_set(row, "state",
                    json_new_string(json_artifact_status_to_string(isNew,isDel)));
    zDownload = mprintf("/raw/%s?name=%s",
                        /* reminder: g.zBaseURL is of course not set for CLI mode. */
                        db_column_text(&q,2),
                        db_column_text(&q,3));
    cson_object_set(row, "downloadPath", json_new_string(zDownload));
    free(zDownload);
  }
  db_finalize(&q);
  return rowsV;
}
Example #9
0
static json_t *CreateMissionNode(MissionSave *m)
{
	json_t *subConfig = json_new_object();
	AddCampaignNode(&m->Campaign, subConfig);
	json_insert_pair_into_object(subConfig, "Password", json_new_string(m->Password));
	AddIntPair(subConfig, "MissionsCompleted", m->MissionsCompleted);
	return subConfig;
}
Example #10
0
int basicTest() {
    printf("%s", "====== basic JSon Test Starts =======\n");

    char *text;
    json_t *root, *entry, *label, *value;
    setlocale (LC_ALL, "");

    // creates the root node
    root = json_new_object();

    // create an entry node
    entry = json_new_object();

    // insert the first label-value pair
    label = json_new_string("name");
    value = json_new_string("Andew");
    json_insert_child(label, value);
    json_insert_child(entry, label);

    // insert the second label-value pair
    label = json_new_string("phone");
    value = json_new_string("555 123 456");
    json_insert_child(label, value);
    json_insert_child(entry, label);

    // inserts that object as a value in a label-value pair
    label = json_new_string("entry");
    json_insert_child(label, entry);

    // inserts that label-value pair into the root object
    json_insert_child(root, label);

    // print the result
    json_tree_to_string(root, &text);
    printf("%s\n",text);

    // clean up
    free(text);
    json_free_value(&root);

    printf("%s", "====== basic JSon Test Ends =======\n");

    return EXIT_SUCCESS;
}
Example #11
0
static json_t *SaveWeapons(const CArray *weapons)
{
	json_t *node = json_new_array();
	for (int i = 0; i < (int)weapons->size; i++)
	{
		const GunDescription **g = CArrayGet(weapons, i);
		json_insert_child(node, json_new_string((*g)->name));
	}
	return node;
}
Example #12
0
static void AddCampaignNode(CampaignEntry *c, json_t *root)
{
	json_t *subConfig = json_new_object();
	// Save relative path so that save files are portable across installs
	char path[CDOGS_PATH_MAX] = "";
	RelPathFromCWD(path, c->Path);
	json_insert_pair_into_object(
		subConfig, "Path", json_new_string(path));
	json_insert_pair_into_object(root, "Campaign", subConfig);
}
Example #13
0
static void test_json_render(void *p)
{
	struct JsonContext *ctx;
	struct JsonValue *list, *dict;

	ctx = json_new_context(NULL, 128);
	tt_assert(ctx);

	list = json_new_list(ctx);
	tt_assert(json_list_append(list, json_new_null(ctx)));
	tt_assert(json_list_append(list, json_new_bool(ctx, 1)));
	tt_assert(json_list_append(list, json_new_bool(ctx, 0)));
	tt_assert(json_list_append(list, json_new_int(ctx, 600)));
	tt_assert(json_list_append(list, json_new_float(ctx, -0.5)));
	tt_assert(json_list_append(list, json_new_string(ctx, "q\\we")));

	str_check(render(list), "[null,true,false,600,-0.5,\"q\\\\we\"]");

	dict = json_new_dict(ctx);
	tt_assert(dict);
	str_check(render(dict), "{}");
	tt_assert(json_dict_put(dict, "k", json_new_list(ctx)));
	str_check(render(dict), "{\"k\":[]}");
	tt_assert(json_dict_put_null(dict, "n"));
	tt_assert(json_dict_put_bool(dict, "b", 1));
	tt_assert(json_dict_put_int(dict, "i", 22));
	tt_assert(json_dict_put_float(dict, "f", 1));
	tt_assert(json_dict_put_string(dict, "s", "qwe"));
	str_check(render(dict), "{\"b\":true,\"f\":1.0,\"i\":22,\"k\":[],\"n\":null,\"s\":\"qwe\"}");

	str_check(render(json_new_string(ctx, "\"\\ low:\a\b\f\n\r\t")), "\"\\\"\\\\ low:\\u0007\\b\\f\\n\\r\\t\"");

	list = json_new_list(ctx);
	tt_assert(json_list_append_null(list));
	tt_assert(json_list_append_bool(list, false));
	tt_assert(json_list_append_int(list, -1));
	tt_assert(json_list_append_float(list, -2));
	tt_assert(json_list_append_string(list, "qz\0foo"));
	str_check(render(list), "[null,false,-1,-2.0,\"qz\"]");

	json_free_context(ctx);
end:;
}
bool jps_method(LSHandle* lshandle, LSMessage *message, void *ctx) {

  bool returnVal = true;
  char line[MAXLINELEN];
  // %%% MAGIC NUMBERS ALERT %%%
  char name[128];

  LSError lserror;
  LSErrorInit(&lserror);

  char *jsonResponse = 0;
  int len = 0;

  json_t *response = json_new_object();

  FILE *fp = popen("/usr/bin/jps", "r");
  if (fp) {
    json_t *array = json_new_array();
    // Skip the first line
    (void)fgets( line, sizeof line, fp);
    while ( fgets( line, sizeof line, fp)) {
      if (sscanf(line, "%*d %*d %*d %*d %*d %*d %*d %127c",
		 (char*)&name) == 1) {
	// %%% HACK ALERT %%%
	*strchr(name,'\n') = 0;
	json_t *object = json_new_object();
	// %%% IGNORING RETURN ALERT %%%
	json_insert_pair_into_object(object, "name", json_new_string(name));
	json_insert_child(array, object);
      }
    }
    if (!pclose(fp)) {
      // %%% IGNORING RETURN ALERT %%%
      json_insert_pair_into_object(response, "returnValue", json_new_true());
      json_insert_pair_into_object(response, "threads", array);
      json_tree_to_string(response, &jsonResponse);
    }
  }

  if (jsonResponse) {
    LSMessageReply(lshandle, message, jsonResponse, &lserror);
    free(jsonResponse);
  } else
    LSMessageReply(lshandle, message, "{\"returnValue\":false,\"errorCode\":-1,\"errorText\":\"Generic error\"}", &lserror);
 
  json_free_value(&response);
  LSErrorFree(&lserror);

  return returnVal;
}
Example #15
0
static void AddInterfaceConfigNode(InterfaceConfig *config, json_t *root)
{
	json_t *subConfig = json_new_object();
	json_insert_pair_into_object(
		subConfig, "ShowFPS", json_new_bool(config->ShowFPS));
	json_insert_pair_into_object(
		subConfig, "ShowTime", json_new_bool(config->ShowTime));
	json_insert_pair_into_object(
		subConfig, "Splitscreen",
		json_new_string(SplitscreenStyleStr(config->Splitscreen)));
	json_insert_pair_into_object(
		subConfig, "ShowHUDMap", json_new_bool(config->ShowHUDMap));
	json_insert_pair_into_object(root, "Interface", subConfig);
}
Example #16
0
json_t *new_entry(char *name, char *phone) {
    json_t *entry, *label, *value;

    // create an entry node
    entry = json_new_object();

    // insert the first label-value pair
    label = json_new_string("name");
    value = json_new_string("Andew");
    json_insert_child(label, value);
    json_insert_child(entry, label);

    // insert the second label-value pair
    label = json_new_string("phone");
    value = json_new_string("555 123 456");
    json_insert_child(label, value);
    json_insert_child(entry, label);

    // inserts that object as a value in a label-value pair
    label = json_new_string("entry");
    json_insert_child(label, entry);

    return label;
}
Example #17
0
json_t*
YtkUtils::mapToJson(const YtkUtils::map_t& map)
{
    json_t* root = json_new_object();
    YtkUtils::map_t::const_iterator pos;
    for(pos = map.begin(); pos != map.end(); ++pos) {
        const char* k = pos->first.c_str();
        const char* val = pos->second.c_str();
        char* t = new char[strlen(val)+1];
        strcpy(t, val);
        char* s = json_escape( t );
        delete[] t;

        json_t *v = json_new_string(s);
        json_insert_pair_into_object(root, k, v);
    }
    return root;
}
Example #18
0
static json_t *SaveCharacters(CharacterStore *s)
{
	json_t *charNode = json_new_array();
	CA_FOREACH(Character, c, s->OtherChars)
		json_t *node = json_new_object();
		AddStringPair(node, "Class", c->Class->Name);
		AddColorPair(node, "Skin", c->Colors.Skin);
		AddColorPair(node, "Arms", c->Colors.Arms);
		AddColorPair(node, "Body", c->Colors.Body);
		AddColorPair(node, "Legs", c->Colors.Legs);
		AddColorPair(node, "Hair", c->Colors.Hair);
		AddIntPair(node, "speed", c->speed);
		json_insert_pair_into_object(
			node, "Gun", json_new_string(c->Gun->name));
		AddIntPair(node, "maxHealth", c->maxHealth);
		AddIntPair(node, "flags", c->flags);
		AddIntPair(node, "probabilityToMove", c->bot->probabilityToMove);
		AddIntPair(node, "probabilityToTrack", c->bot->probabilityToTrack);
		AddIntPair(node, "probabilityToShoot", c->bot->probabilityToShoot);
		AddIntPair(node, "actionDelay", c->bot->actionDelay);
		json_insert_child(charNode, node);
	CA_FOREACH_END()
	return charNode;
}
Example #19
0
static json_t *SaveMissions(CArray *a)
{
	json_t *missionsNode = json_new_array();
	for (int i = 0; i < (int)a->size; i++)
	{
		json_t *node = json_new_object();
		Mission *mission = CArrayGet(a, i);
		AddStringPair(node, "Title", mission->Title);
		AddStringPair(node, "Description", mission->Description);
		AddStringPair(node, "Type", MapTypeStr(mission->Type));
		AddIntPair(node, "Width", mission->Size.x);
		AddIntPair(node, "Height", mission->Size.y);

		AddIntPair(node, "WallStyle", mission->WallStyle);
		AddIntPair(node, "FloorStyle", mission->FloorStyle);
		AddIntPair(node, "RoomStyle", mission->RoomStyle);
		AddIntPair(node, "ExitStyle", mission->ExitStyle);
		AddIntPair(node, "KeyStyle", mission->KeyStyle);
		AddStringPair(node, "DoorStyle", mission->DoorStyle);

		json_insert_pair_into_object(
			node, "Objectives", SaveObjectives(&mission->Objectives));
		json_insert_pair_into_object(
			node, "Enemies", SaveIntArray(&mission->Enemies));
		json_insert_pair_into_object(
			node, "SpecialChars", SaveIntArray(&mission->SpecialChars));
		json_t *modsNode = json_new_array();
		for (int j = 0; j < (int)mission->MapObjectDensities.size; j++)
		{
			const MapObjectDensity *mod =
				CArrayGet(&mission->MapObjectDensities, j);
			json_t *modNode = json_new_object();
			AddStringPair(modNode, "MapObject", mod->M->Name);
			AddIntPair(modNode, "Density", mod->Density);
			json_insert_child(modsNode, modNode);
		}
		json_insert_pair_into_object(node, "MapObjectDensities", modsNode);

		AddIntPair(node, "EnemyDensity", mission->EnemyDensity);
		json_insert_pair_into_object(
			node, "Weapons", SaveWeapons(&mission->Weapons));

		json_insert_pair_into_object(
			node, "Song", json_new_string(mission->Song));

		AddColorPair(node, "WallMask", mission->WallMask);
		AddColorPair(node, "FloorMask", mission->FloorMask);
		AddColorPair(node, "RoomMask", mission->RoomMask);
		AddColorPair(node, "AltMask", mission->AltMask);

		switch (mission->Type)
		{
		case MAPTYPE_CLASSIC:
			AddIntPair(node, "Walls", mission->u.Classic.Walls);
			AddIntPair(node, "WallLength", mission->u.Classic.WallLength);
			AddIntPair(
				node, "CorridorWidth", mission->u.Classic.CorridorWidth);
			json_insert_pair_into_object(
				node, "Rooms", SaveClassicRooms(mission));
			AddIntPair(node, "Squares", mission->u.Classic.Squares);
			json_insert_pair_into_object(
				node, "Doors", SaveClassicDoors(mission));
			json_insert_pair_into_object(
				node, "Pillars", SaveClassicPillars(mission));
			break;
		case MAPTYPE_STATIC:
			{
				json_insert_pair_into_object(
					node, "Tiles", SaveStaticTiles(mission));
				json_insert_pair_into_object(
					node, "StaticItems", SaveStaticItems(mission));
				json_insert_pair_into_object(
					node, "StaticWrecks", SaveStaticWrecks(mission));
				json_insert_pair_into_object(
					node, "StaticCharacters", SaveStaticCharacters(mission));
				json_insert_pair_into_object(
					node, "StaticObjectives", SaveStaticObjectives(mission));
				json_insert_pair_into_object(
					node, "StaticKeys", SaveStaticKeys(mission));

				json_insert_pair_into_object(
					node, "Start", SaveVec2i(mission->u.Static.Start));
				json_t *exitNode = json_new_object();
				json_insert_pair_into_object(
					exitNode, "Start",
					SaveVec2i(mission->u.Static.Exit.Start));
				json_insert_pair_into_object(
					exitNode, "End",
					SaveVec2i(mission->u.Static.Exit.End));
				json_insert_pair_into_object(node, "Exit", exitNode);
			}
			break;
		default:
			assert(0 && "unknown map type");
			break;
		}

		json_insert_child(missionsNode, node);
	}
	return missionsNode;
}
/*
** Impl for /json/report/run
**
** Options/arguments:
**
** report=int (CLI: -report # or -r #) is the report number to run.
**
** limit=int (CLI: -limit # or -n #) -n is for compat. with other commands.
**
** format=a|o Specifies result format: a=each row is an arry, o=each
** row is an object.  Default=o.
*/
static cson_value * json_report_run(){
  int nReport;
  Stmt q = empty_Stmt;
  cson_object * pay = NULL;
  cson_array * tktList = NULL;
  char const * zFmt;
  char * zTitle = NULL;
  Blob sql = empty_blob;
  int limit = 0;
  cson_value * colNames = NULL;
  int i;

  if(!g.perm.RdTkt){
    json_set_err(FSL_JSON_E_DENIED,
                 "Requires 'r' privileges.");
    return NULL;
  }
  nReport = json_report_get_number(3);
  if(nReport <=0){
    json_set_err(FSL_JSON_E_MISSING_ARGS,
                 "Missing or invalid 'number' (-n) parameter.");
    goto error;
  }
  zFmt = json_find_option_cstr2("format",NULL,"f",3);
  if(!zFmt) zFmt = "o";
  db_prepare(&q,
             "SELECT sqlcode, "
             " title"
             " FROM reportfmt"
             " WHERE rn=%d",
             nReport);
  if(SQLITE_ROW != db_step(&q)){
    json_set_err(FSL_JSON_E_INVALID_ARGS,
                 "Report number %d not found.",
                 nReport);
    db_finalize(&q);
    goto error;
  }

  limit = json_find_option_int("limit",NULL,"n",-1);

  
  /* Copy over report's SQL...*/
  blob_append(&sql, db_column_text(&q,0), -1);
  zTitle = mprintf("%s", db_column_text(&q,1));
  db_finalize(&q);
  db_prepare(&q, "%s", blob_str(&sql));

  /** Build the response... */
  pay = cson_new_object();

  cson_object_set(pay, "report", json_new_int(nReport));
  cson_object_set(pay, "title", json_new_string(zTitle));
  if(limit>0){
    cson_object_set(pay, "limit", json_new_int((limit<0) ? 0 : limit));
  }
  free(zTitle);
  zTitle = NULL;

  if(g.perm.TktFmt){
    cson_object_set(pay, "sqlcode",
                    cson_value_new_string(blob_str(&sql),
                                          (unsigned int)blob_size(&sql)));
  }
  blob_reset(&sql);

  colNames = cson_sqlite3_column_names(q.pStmt);
  cson_object_set( pay, "columnNames", colNames);
  for( i = 0 ; ((limit>0) ?(i < limit) : 1)
         && (SQLITE_ROW == db_step(&q));
       ++i){
    cson_value * row = ('a'==*zFmt)
      ? cson_sqlite3_row_to_array(q.pStmt)
      : cson_sqlite3_row_to_object2(q.pStmt,
                                    cson_value_get_array(colNames));
    ;
    if(row && !tktList){
      tktList = cson_new_array();
    }
    cson_array_append(tktList, row);
  }
  db_finalize(&q);
  cson_object_set(pay, "tickets",
                  tktList ? cson_array_value(tktList) : cson_value_null());

  goto end;

  error:
  assert(0 != g.json.resultCode);
  cson_value_free( cson_object_value(pay) );
  pay = NULL;
  end:

  return pay ? cson_object_value(pay) : NULL;

}
cson_value * json_artifact_file(cson_object * zParent, int rid){
  cson_object * pay = NULL;
  Stmt q = empty_Stmt;
  cson_array * checkin_arr = NULL;
  char contentFormat;
  i64 contentSize = -1;
  char * parentUuid;
  if( ! g.perm.Read ){
    json_set_err(FSL_JSON_E_DENIED,
                 "Requires 'o' privileges.");
    return NULL;
  }
  
  pay = zParent;

  contentFormat = json_artifact_get_content_format_flag();
  if( 0 != contentFormat ){
    Blob content = empty_blob;
    const char *zMime;
    char const * zFormat = (contentFormat<1) ? "raw" : "html";
    content_get(rid, &content);
    zMime = mimetype_from_content(&content);
    cson_object_set(zParent, "contentType",
                    json_new_string(zMime ? zMime : "text/plain"));
    if(!zMime){/* text/plain */
      if(0 < blob_size(&content)){
        if( 0 < contentFormat ){/*HTML-size it*/
          Blob html = empty_blob;
          wiki_convert(&content, &html, 0);
          assert( blob_size(&content) < blob_size(&html) );
          blob_swap( &html, &content );
          assert( blob_size(&content) > blob_size(&html) );
          blob_reset( &html );
        }/*else as-is*/
      }
      cson_object_set(zParent, "content",
                      cson_value_new_string(blob_str(&content),
                                            (unsigned int)blob_size(&content)));
    }/*else binary: ignore*/
    contentSize = blob_size(&content);
    cson_object_set(zParent, "contentSize", json_new_int(contentSize) );
    cson_object_set(zParent, "contentFormat", json_new_string(zFormat) );
    blob_reset(&content);
  }
  contentSize = db_int64(-1, "SELECT size FROM blob WHERE rid=%d", rid);
  assert( -1 < contentSize );
  cson_object_set(zParent, "size", json_new_int(contentSize) );

  parentUuid = db_text(NULL,
                       "SELECT DISTINCT p.uuid "
                       "FROM blob p, blob f, mlink m "
                       "WHERE m.pid=p.rid "
                       "AND m.fid=f.rid "
                       "AND f.rid=%d",
                       rid
                       );
  if(parentUuid){
    cson_object_set( zParent, "parent", json_new_string(parentUuid) );
    fossil_free(parentUuid);
  }
  
  /* Find checkins associated with this file... */
  db_prepare(&q,
      "SELECT filename.name AS name, "
      "  (mlink.pid==0) AS isNew,"
      "  (mlink.fid==0) AS isDel,"
      "  cast(strftime('%%s',event.mtime) as int) AS timestamp,"
      "  coalesce(event.ecomment,event.comment) as comment,"
      "  coalesce(event.euser,event.user) as user,"
#if 0
      "  a.size AS size," /* same for all checkins. */
#endif
      "  b.uuid as checkin, "
#if 0
      "  mlink.mperm as mperm,"
#endif
      "  coalesce((SELECT value FROM tagxref"
                      "  WHERE tagid=%d AND tagtype>0 AND "
                      " rid=mlink.mid),'trunk') as branch"
      "  FROM mlink, filename, event, blob a, blob b"
      " WHERE filename.fnid=mlink.fnid"
      "   AND event.objid=mlink.mid"
      "   AND a.rid=mlink.fid"
      "   AND b.rid=mlink.mid"
      "   AND mlink.fid=%d"
      "   ORDER BY filename.name, event.mtime",
      TAG_BRANCH, rid
    );
  /* TODO: add a "state" flag for the file in each checkin,
     e.g. "modified", "new", "deleted".
   */
  checkin_arr = cson_new_array(); 
  cson_object_set(pay, "checkins", cson_array_value(checkin_arr));
  while( (SQLITE_ROW==db_step(&q) ) ){
    cson_object * row = cson_value_get_object(cson_sqlite3_row_to_object(q.pStmt));
    /* FIXME: move this isNew/isDel stuff into an SQL CASE statement. */
    char const isNew = cson_value_get_bool(cson_object_get(row,"isNew"));
    char const isDel = cson_value_get_bool(cson_object_get(row,"isDel"));
    cson_object_set(row, "isNew", NULL);
    cson_object_set(row, "isDel", NULL);
    cson_object_set(row, "state",
                    json_new_string(json_artifact_status_to_string(isNew, isDel)));
    cson_array_append( checkin_arr, cson_object_value(row) );
  }
  db_finalize(&q);
  return cson_object_value(pay);
}
Example #22
0
/*
** Implementation of the /json/status page.
**
*/
cson_value * json_page_status(){
  Stmt q = empty_Stmt;
  cson_object * oPay;
  /*cson_object * files;*/
  int vid, nErr = 0;
  cson_object * tmpO;
  char * zTmp;
  i64 iMtime;
  cson_array * aFiles;

  if(!db_open_local(0)){
    json_set_err(FSL_JSON_E_DB_NEEDS_CHECKOUT, NULL);
    return NULL;
  }
  oPay = cson_new_object();
  cson_object_set(oPay, "repository",
                  json_new_string(db_repository_filename()));
  cson_object_set(oPay, "localRoot",
                  json_new_string(g.zLocalRoot));
  vid = db_lget_int("checkout", 0);
  if(!vid){
      json_set_err( FSL_JSON_E_UNKNOWN, "Can this even happen?" );
      return 0;
  }
  /* TODO: dupe show_common_info() state */
  tmpO = cson_new_object();
  cson_object_set(oPay, "checkout", cson_object_value(tmpO));

  zTmp = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", vid);
  cson_object_set(tmpO, "uuid", json_new_string(zTmp) );
  free(zTmp);

  cson_object_set( tmpO, "tags", json_tags_for_checkin_rid(vid, 0) );

  /* FIXME: optimize the datetime/timestamp queries into 1 query. */
  zTmp = db_text(0, "SELECT datetime(mtime) || "
                 "' UTC' FROM event WHERE objid=%d",
                 vid);
  cson_object_set(tmpO, "datetime", json_new_string(zTmp));
  free(zTmp);
  iMtime = db_int64(0, "SELECT CAST(strftime('%%s',mtime) AS INTEGER) "
                    "FROM event WHERE objid=%d", vid);
  cson_object_set(tmpO, "timestamp",
                  cson_value_new_integer((cson_int_t)iMtime));
#if 0
    /* TODO: add parent artifact info */
  tmpO = cson_new_object();
  cson_object_set( oPay, "parent", cson_object_value(tmpO) );
  cson_object_set( tmpO, "uuid", TODO );
  cson_object_set( tmpO, "timestamp", TODO );
#endif

  /* Now get the list of non-pristine files... */
  aFiles = cson_new_array();
  cson_object_set( oPay, "files", cson_array_value( aFiles ) );

  db_prepare(&q,
    "SELECT pathname, deleted, chnged, rid, coalesce(origname!=pathname,0)"
    "  FROM vfile "
    " WHERE is_selected(id)"
    "   AND (chnged OR deleted OR rid=0 OR pathname!=origname) ORDER BY 1"
  );
  while( db_step(&q)==SQLITE_ROW ){
    const char *zPathname = db_column_text(&q,0);
    int isDeleted = db_column_int(&q, 1);
    int isChnged = db_column_int(&q,2);
    int isNew = db_column_int(&q,3)==0;
    int isRenamed = db_column_int(&q,4);
    cson_object * oFile;
    char const * zStatus = "???";
    char * zFullName = mprintf("%s%s", g.zLocalRoot, zPathname);
    if( isDeleted ){
      zStatus = "deleted";
    }else if( isNew ){
      zStatus = "new" /* maintenance reminder: MUST come
                         BEFORE the isChnged checks. */;
    }else if( isRenamed ){
      zStatus = "renamed";
    }else if( !file_wd_isfile_or_link(zFullName) ){
      if( file_access(zFullName, F_OK)==0 ){
        zStatus = "notAFile";
        ++nErr;
      }else{
        zStatus = "missing";
        ++nErr;
      }
    }else if( 2==isChnged ){
      zStatus = "updatedByMerge";
    }else if( 3==isChnged ){
      zStatus = "addedByMerge";
    }else if( 4==isChnged ){
      zStatus = "updatedByIntegrate";
    }else if( 5==isChnged ){
      zStatus = "addedByIntegrate";
    }else if( 1==isChnged ){
      if( file_contains_merge_marker(zFullName) ){
        zStatus = "conflict";
      }else{
        zStatus = "edited";
      }
    }

    oFile = cson_new_object();
    cson_array_append( aFiles, cson_object_value(oFile) );
    /* optimization potential: move these keys into cson_strings
       to take advantage of refcounting. */
    cson_object_set( oFile, "name", json_new_string( zPathname ) );
    cson_object_set( oFile, "status", json_new_string( zStatus ) );

    free(zFullName);
  }
  cson_object_set( oPay, "errorCount", json_new_int( nErr ) );
  db_finalize(&q);

#if 0
  /* TODO: add "merged with" status.  First need (A) to decide on a
     structure and (B) to set up some tests for the multi-merge
     case.*/
  db_prepare(&q, "SELECT uuid, id FROM vmerge JOIN blob ON merge=rid"
                 " WHERE id<=0");
  while( db_step(&q)==SQLITE_ROW ){
    const char *zLabel = "MERGED_WITH";
    switch( db_column_int(&q, 1) ){
      case -1:  zLabel = "CHERRYPICK ";  break;
      case -2:  zLabel = "BACKOUT    ";  break;
      case -4:  zLabel = "INTEGRATE  ";  break;
    }
    blob_append(report, zPrefix, nPrefix);
    blob_appendf(report, "%s %s\n", zLabel, db_column_text(&q, 0));
  }
  db_finalize(&q);
  if( nErr ){
    fossil_fatal("aborting due to prior errors");
  }
#endif
  return cson_object_value( oPay );
}
Example #23
0
/*
** Implementation of the /json/login page.
**
*/
cson_value * json_page_login(){
  char preciseErrors = /* if true, "complete" JSON error codes are used,
                          else they are "dumbed down" to a generic login
                          error code.
                       */
#if 1
    g.json.errorDetailParanoia ? 0 : 1
#else
    0
#endif
    ;
  /*
    FIXME: we want to check the GET/POST args in this order:

    - GET: name, n, password, p
    - POST: name, password

    but a bug in cgi_parameter() is breaking that, causing PD() to
    return the last element of the PATH_INFO instead.

    Summary: If we check for P("name") first, then P("n"),
    then ONLY a GET param of "name" will match ("n"
    is not recognized). If we reverse the order of the
    checks then both forms work. Strangely enough, the
    "p"/"password" check is not affected by this.
   */
  char const * name = cson_value_get_cstr(json_req_payload_get("name"));
  char const * pw = NULL;
  char const * anonSeed = NULL;
  cson_value * payload = NULL;
  int uid = 0;
  /* reminder to self: Fossil internally (for the sake of /wiki)
     interprets paths in the form /foo/bar/baz such that P("name") ==
     "bar/baz". This collides with our name/password checking, and
     thus we do some rather elaborate name=... checking.
  */
  pw = cson_value_get_cstr(json_req_payload_get("password"));
  if( !pw ){
    pw = PD("p",NULL);
    if( !pw ){
      pw = PD("password",NULL);
    }
  }
  if(!pw){
    g.json.resultCode = preciseErrors
      ? FSL_JSON_E_LOGIN_FAILED_NOPW
      : FSL_JSON_E_LOGIN_FAILED;
    return NULL;
  }

  if( !name ){
    name = PD("n",NULL);
    if( !name ){
      name = PD("name",NULL);
      if( !name ){
        g.json.resultCode = preciseErrors
          ? FSL_JSON_E_LOGIN_FAILED_NONAME
          : FSL_JSON_E_LOGIN_FAILED;
        return NULL;
      }
    }
  }

  if(0 == strcmp("anonymous",name)){
    /* check captcha/seed values... */
    enum { SeedBufLen = 100 /* in some JSON tests i once actually got an
                           80-digit number.
                        */
    };
    static char seedBuffer[SeedBufLen];
    cson_value const * jseed = json_getenv(FossilJsonKeys.anonymousSeed);
    seedBuffer[0] = 0;
    if( !jseed ){
      jseed = json_req_payload_get(FossilJsonKeys.anonymousSeed);
      if( !jseed ){
        jseed = json_getenv("cs") /* name used by HTML interface */;
      }
    }
    if(jseed){
      if( cson_value_is_number(jseed) ){
        sprintf(seedBuffer, "%"CSON_INT_T_PFMT, cson_value_get_integer(jseed));
        anonSeed = seedBuffer;
      }else if( cson_value_is_string(jseed) ){
        anonSeed = cson_string_cstr(cson_value_get_string(jseed));
      }
    }
    if(!anonSeed){
      g.json.resultCode = preciseErrors
        ? FSL_JSON_E_LOGIN_FAILED_NOSEED
        : FSL_JSON_E_LOGIN_FAILED;
      return NULL;
    }
  }

#if 0
  {
    /* only for debugging the PD()-incorrect-result problem */
    cson_object * o = NULL;
    uid = login_search_uid( name, pw );
    payload = cson_value_new_object();
    o = cson_value_get_object(payload);
    cson_object_set( o, "n", cson_value_new_string(name,strlen(name)));
    cson_object_set( o, "p", cson_value_new_string(pw,strlen(pw)));
    return payload;
  }
#endif
  uid = anonSeed
    ? login_is_valid_anonymous(name, pw, anonSeed)
    : login_search_uid(name, pw)
    ;
  if( !uid ){
    g.json.resultCode = preciseErrors
      ? FSL_JSON_E_LOGIN_FAILED_NOTFOUND
      : FSL_JSON_E_LOGIN_FAILED;
    return NULL;
  }else{
    char * cookie = NULL;
    cson_object * po;
    char * cap = NULL;
    if(anonSeed){
      login_set_anon_cookie(NULL, &cookie);
    }else{
      login_set_user_cookie(name, uid, &cookie);
    }
    payload = cson_value_new_object();
    po = cson_value_get_object(payload);
    cson_object_set(po, "authToken", json_new_string(cookie));
    free(cookie);
    cson_object_set(po, "name", json_new_string(name));
    cap = db_text(NULL, "SELECT cap FROM user WHERE login=%Q", name);
    cson_object_set(po, "capabilities", cap ? json_new_string(cap) : cson_value_null() );
    free(cap);        
    cson_object_set(po, "loginCookieName", json_new_string( login_cookie_name() ) );
    /* TODO: add loginExpiryTime to the payload. To do this properly
       we "should" add an ([unsigned] int *) to
       login_set_user_cookie() and login_set_anon_cookie(), to which
       the expiry time is assigned. (Remember that JSON doesn't do
       unsigned int.)

       For non-anonymous users we could also simply query the
       user.cexpire db field after calling login_set_user_cookie(),
       but for anonymous we need to get the time when the cookie is
       set because anon does not get a db entry like normal users
       do. Anonymous cookies currently have a hard-coded lifetime in
       login_set_anon_cookie() (currently 6 hours), which we "should
       arguably" change to use the time configured for non-anonymous
       users (see login_set_user_cookie() for details).
    */
    return payload;
  }
}
/*
** Generates an artifact Object for the given rid,
** which must refer to a Checkin.
**
** Returned value is NULL or an Object owned by the caller.
*/
cson_value * json_artifact_for_ci( int rid, char showFiles ){
  cson_value * v = NULL;
  Stmt q = empty_Stmt;
  static cson_value * eventTypeLabel = NULL;
  if(!eventTypeLabel){
    eventTypeLabel = json_new_string("checkin");
    json_gc_add("$EVENT_TYPE_LABEL(commit)", eventTypeLabel);
  }
  
  db_prepare(&q,
             "SELECT b.uuid, "
             " cast(strftime('%%s',e.mtime) as int), "
             " strftime('%%s',e.omtime),"
             " e.user, "
             " e.comment"
             " FROM blob b, event e"
             " WHERE b.rid=%d"
             "   AND e.objid=%d",
             rid, rid
             );
  if( db_step(&q)==SQLITE_ROW ){
    cson_object * o;
    cson_value * tmpV = NULL;
    const char *zUuid = db_column_text(&q, 0);
    const char *zUser;
    const char *zComment;
    char * zEUser, * zEComment;
    int mtime, omtime;
    v = cson_value_new_object();
    o = cson_value_get_object(v);
#define SET(K,V) cson_object_set(o,(K), (V))
    SET("type", eventTypeLabel );
    SET("uuid",json_new_string(zUuid));
    SET("isLeaf", cson_value_new_bool(is_a_leaf(rid)));

    mtime = db_column_int(&q,1);
    SET("timestamp",json_new_int(mtime));
    omtime = db_column_int(&q,2);
    if(omtime && (omtime!=mtime)){
      SET("originTime",json_new_int(omtime));
    }

    zUser = db_column_text(&q,3);
    zEUser = db_text(0,
                   "SELECT value FROM tagxref WHERE tagid=%d AND rid=%d",
                   TAG_USER, rid);
    if(zEUser){
      SET("user", json_new_string(zEUser));
      if(0!=strcmp(zEUser,zUser)){
        SET("originUser",json_new_string(zUser));
      }
      free(zEUser);
    }else{
      SET("user",json_new_string(zUser));
    }

    zComment = db_column_text(&q,4);
    zEComment = db_text(0, 
                   "SELECT value FROM tagxref WHERE tagid=%d AND rid=%d",
                   TAG_COMMENT, rid);
    if(zEComment){
      SET("comment",json_new_string(zEComment));
      if(0 != strcmp(zEComment,zComment)){
        SET("originComment", json_new_string(zComment));
      }
      free(zEComment);
    }else{
      SET("comment",json_new_string(zComment));
    }

    tmpV = json_parent_uuids_for_ci(rid);
    if(tmpV){
      SET("parents", tmpV);
    }

    tmpV = json_tags_for_checkin_rid(rid,0);
    if(tmpV){
      SET("tags",tmpV);
    }

    if( showFiles ){
      tmpV = json_get_changed_files(rid, 1);
      if(tmpV){
        SET("files",tmpV);
      }
    }

#undef SET
  }
  db_finalize(&q);
  return v;
}
/*
** Impl of /json/artifact. This basically just determines the type of
** an artifact and forwards the real work to another function.
*/
cson_value * json_page_artifact(){
  cson_object * pay = NULL;
  char const * zName = NULL;
  char const * zType = NULL;
  char const * zUuid = NULL;
  cson_value * entry = NULL;
  Blob uuid = empty_blob;
  int rc;
  int rid = 0;
  ArtifactDispatchEntry const * dispatcher = &ArtifactDispatchList[0];
  zName = json_find_option_cstr2("name", NULL, NULL, g.json.dispatchDepth+1);
  if(!zName || !*zName) {
    json_set_err(FSL_JSON_E_MISSING_ARGS,
                 "Missing 'name' argument.");
    return NULL;
  }

  if( validate16(zName, strlen(zName)) ){
    if( db_exists("SELECT 1 FROM ticket WHERE tkt_uuid GLOB '%q*'", zName) ){
      zType = "ticket";
      goto handle_entry;
    }
    if( db_exists("SELECT 1 FROM tag WHERE tagname GLOB 'event-%q*'", zName) ){
      zType = "tag";
      goto handle_entry;
    }
  }
  blob_set(&uuid,zName);
  rc = name_to_uuid(&uuid,-1,"*");
  /* FIXME: check for a filename if all else fails. */
  if(1==rc){
    g.json.resultCode = FSL_JSON_E_RESOURCE_NOT_FOUND;
    goto error;
  }else if(2==rc){
    g.json.resultCode = FSL_JSON_E_AMBIGUOUS_UUID;
    goto error;
  }
  zUuid = blob_str(&uuid);
  rid = db_int(0, "SELECT rid FROM blob WHERE uuid=%Q", zUuid);
  if(0==rid){
    g.json.resultCode = FSL_JSON_E_RESOURCE_NOT_FOUND;
    goto error;
  }

  if( db_exists("SELECT 1 FROM mlink WHERE mid=%d", rid)
      || db_exists("SELECT 1 FROM plink WHERE cid=%d", rid)
      || db_exists("SELECT 1 FROM plink WHERE pid=%d", rid)){
    zType = "checkin";
    goto handle_entry;
  }else if( db_exists("SELECT 1 FROM tagxref JOIN tag USING(tagid)"
                      " WHERE rid=%d AND tagname LIKE 'wiki-%%'", rid) ){
    zType = "wiki";
    goto handle_entry;
  }else if( db_exists("SELECT 1 FROM tagxref JOIN tag USING(tagid)"
                      " WHERE rid=%d AND tagname LIKE 'tkt-%%'", rid) ){
    zType = "ticket";
    goto handle_entry;
  }else if ( db_exists("SELECT 1 FROM mlink WHERE fid = %d", rid) ){
    zType = "file";
    goto handle_entry;
  }else{
    g.json.resultCode = FSL_JSON_E_RESOURCE_NOT_FOUND;
    goto error;
  }

  error:
  assert( 0 != g.json.resultCode );
  goto veryend;

  handle_entry:
  pay = cson_new_object();
  assert( (NULL != zType) && "Internal dispatching error." );
  for( ; dispatcher->name; ++dispatcher ){
    if(0!=strcmp(dispatcher->name, zType)){
      continue;
    }else{
      entry = (*dispatcher->func)(pay, rid);
      break;
    }
  }
  if(!g.json.resultCode){
    assert( NULL != entry );
    assert( NULL != zType );
    cson_object_set( pay, "type", json_new_string(zType) );
    cson_object_set( pay, "uuid", json_new_string(zUuid) );
    /*cson_object_set( pay, "name", json_new_string(zName ? zName : zUuid) );*/
    /*cson_object_set( pay, "rid", cson_value_new_integer(rid) );*/
    if(cson_value_is_object(entry) && (cson_value_get_object(entry) != pay)){
      cson_object_set(pay, "artifact", entry);
    }
  }
  veryend:
  blob_reset(&uuid);
  if(g.json.resultCode && pay){
    cson_free_object(pay);
    pay = NULL;
  }
  return cson_object_value(pay);
}
Example #26
0
/* JSON metadata dumping */
static void amf_to_json(const amf_data * data, json_t ** object) {
    if (data != NULL) {
        json_t * value;
        amf_node * node;
        time_t time;
        struct tm * t;
        char str[128];
        char * escaped_str;

        switch (data->type) {
            case AMF_TYPE_NUMBER:
                sprintf(str, "%.12g", data->number_data);
                *object = json_new_number(str);
                break;
            case AMF_TYPE_BOOLEAN:
                *object = (data->boolean_data) ? json_new_true() : json_new_false();
                break;
            case AMF_TYPE_STRING:
                escaped_str = json_escape((char *)amf_string_get_bytes(data));
                *object = json_new_string(escaped_str);
                free(escaped_str);
                break;
            case AMF_TYPE_OBJECT:
                *object = json_new_object();
                node = amf_object_first(data);
                while (node != NULL) {
                    amf_to_json(amf_object_get_data(node), &value);
                    escaped_str = json_escape((char *)amf_string_get_bytes(amf_object_get_name(node)));
                    json_insert_pair_into_object(*object, escaped_str, value);
                    free(escaped_str);
                    node = amf_object_next(node);
                }
                break;
            case AMF_TYPE_NULL:
            case AMF_TYPE_UNDEFINED:
                *object = json_new_null();
                break;
            case AMF_TYPE_ASSOCIATIVE_ARRAY:
                *object = json_new_object();
                node = amf_associative_array_first(data);
                while (node != NULL) {
                    amf_to_json(amf_associative_array_get_data(node), &value);
                    json_insert_pair_into_object(*object, (const char *)amf_string_get_bytes(amf_associative_array_get_name(node)), value);
                    node = amf_associative_array_next(node);
                }
                break;
            case AMF_TYPE_ARRAY:
                *object = json_new_array();
                node = amf_array_first(data);
                while (node != NULL) {
                    amf_to_json(amf_array_get(node), &value);
                    json_insert_child(*object, value);
                    node = amf_array_next(node);
                }
                break;
            case AMF_TYPE_DATE:
                time = amf_date_to_time_t(data);
                tzset();
                t = localtime(&time);
                strftime(str, sizeof(str), "%Y-%m-%dT%H:%M:%S", t);
                *object = json_new_string(str);
                break;
            case AMF_TYPE_XML: break;
            case AMF_TYPE_CLASS: break;
            default: break;
        }
    }
}
Example #27
0
/*
** Implementation of /json/timeline/ticket.
**
*/
static cson_value * json_timeline_ticket(){
  /* This code is 95% the same as json_timeline_ci(), by the way. */
  cson_value * payV = NULL;
  cson_object * pay = NULL;
  cson_value * tmp = NULL;
  cson_value * listV = NULL;
  cson_array * list = NULL;
  int check = 0;
  Stmt q = empty_Stmt;
  Blob sql = empty_blob;
  if( !g.perm.RdTkt && !g.perm.Read ){
    json_set_err(FSL_JSON_E_DENIED, "Ticket timeline requires 'o' or 'r' access.");
    return NULL;
  }
  payV = cson_value_new_object();
  pay = cson_value_get_object(payV);
  check = json_timeline_setup_sql( "t", &sql, pay );
  if(check){
    json_set_err(check, "Query initialization failed.");
    goto error;
  }

  db_multi_exec("%s", blob_buffer(&sql) /*safe-for-%s*/);
#define SET(K) if(0!=(check=cson_object_set(pay,K,tmp))){ \
    json_set_err((cson_rc.AllocError==check)        \
                 ? FSL_JSON_E_ALLOC : FSL_JSON_E_UNKNOWN,      \
                 "Object property insertion failed."); \
    goto error;\
  } (void)0

#if 0
  /* only for testing! */
  tmp = cson_value_new_string(blob_buffer(&sql),strlen(blob_buffer(&sql)));
  SET("timelineSql");
#endif

  blob_reset(&sql);
  /*
    REMINDER/FIXME(?): we have both uuid (the change uuid?)  and
    ticketUuid (the actual ticket). This is different from the wiki
    timeline, where we only have the wiki page uuid.
   */
  db_prepare(&q, "SELECT rid AS rid,"
             " uuid AS uuid,"
             " mtime AS timestamp,"
#if 0
             " timestampString AS timestampString,"
#endif
             " user AS user,"
             " eventType AS eventType,"
             " comment AS comment,"
             " brief AS briefComment"
             " FROM json_timeline"
             " ORDER BY rowid");
  listV = cson_value_new_array();
  list = cson_value_get_array(listV);
  tmp = listV;
  SET("timeline");
  while( (SQLITE_ROW == db_step(&q) )){
    /* convert each row into a JSON object...*/
    int rc;
    int const rid = db_column_int(&q,0);
    Manifest * pMan = NULL;
    cson_value * rowV;
    cson_object * row;
    /*printf("rid=%d\n",rid);*/
    pMan = manifest_get(rid, CFTYPE_TICKET, 0);
    if(!pMan){
      /* this might be an attachment? I'm seeing this with
         rid 15380, uuid [1292fef05f2472108].

         /json/artifact/1292fef05f2472108 returns not-found,
         probably because we haven't added artifact/ticket
         yet(?).
      */
      continue;
    }

    rowV = cson_sqlite3_row_to_object(q.pStmt);
    row = cson_value_get_object(rowV);
    if(!row){
      manifest_destroy(pMan);
      json_warn( FSL_JSON_W_ROW_TO_JSON_FAILED,
                 "Could not convert at least one timeline result row to JSON." );
      continue;
    }
    /* FIXME: certainly there's a more efficient way for use to get
       the ticket UUIDs?
    */
    cson_object_set(row,"ticketUuid",json_new_string(pMan->zTicketUuid));
    manifest_destroy(pMan);
    rc = cson_array_append( list, rowV );
    if( 0 != rc ){
      cson_value_free(rowV);
      g.json.resultCode = (cson_rc.AllocError==rc)
        ? FSL_JSON_E_ALLOC
        : FSL_JSON_E_UNKNOWN;
      goto error;
    }
  }
#undef SET
  goto ok;
  error:
  assert( 0 != g.json.resultCode );
  cson_value_free(payV);
  payV = NULL;
  ok:
  blob_reset(&sql);
  db_finalize(&q);
  return payV;
}
bool stop_method(LSHandle* lshandle, LSMessage *message, void *ctx) {

  bool returnVal = true;
  char line[MAXLINELEN];
  // %%% MAGIC NUMBERS ALERT %%%
  char name[128];
  char status[128];

  LSError lserror;
  LSErrorInit(&lserror);

  char *jsonResponse = 0;
  int len = 0;

  json_t *object = json_parse_document(LSMessageGetPayload(message));

  json_t *id = json_find_first_label(object, "id");               
  if (strspn(id->child->text, ALLOWED_CHARS) != strlen(id->child->text)) {
    LSMessageReply(lshandle, message, "{\"returnValue\":false,\"errorCode\":-1,\"errorText\":\"Invalid id\"}", &lserror);
    LSErrorFree(&lserror);
    return true;
  }

  // %%% MAGIC NUMBERS ALERT %%%
  char command[128];
  char format[128];

  // %%% IGNORING RETURN ALERT %%%
  sprintf((char *)&command, "/sbin/initctl stop %s 2>&1", id->child->text);

  json_t *response = json_new_object();

  FILE *fp = popen(command, "r");
  if (fp) {
    while ( fgets( line, sizeof line, fp)) {
      if (sscanf(line, "(%*d/%*d) Job not changed: %127s\n", (char *)&name) == 1) {
	// %%% IGNORING RETURN ALERT %%%
	json_insert_pair_into_object(response, "status", json_new_string("Job not changed"));
      }
      else if (sscanf(line, "(%*d/%*d) %s %127c\n", (char *)&name, (char *)&status) == 2) {
	// %%% HACK ALERT %%%
	*strchr(status,'\n') = 0;
	// %%% IGNORING RETURN ALERT %%%
	json_insert_pair_into_object(response, "status", json_new_string(status));
      }
    }
    if (!pclose(fp)) {
      // %%% IGNORING RETURN ALERT %%%
      json_insert_pair_into_object(response, "returnValue", json_new_true());
    }
    else {
      // %%% IGNORING RETURN ALERT %%%
      json_insert_pair_into_object(response, "returnValue", json_new_false());
    }
    json_tree_to_string(response, &jsonResponse);
  }

  if (jsonResponse) {
    LSMessageReply(lshandle, message, jsonResponse, &lserror);
    free(jsonResponse);
  } else
    LSMessageReply(lshandle, message, "{\"returnValue\":false,\"errorCode\":-1,\"errorText\":\"Generic error\"}", &lserror);
 
  json_free_value(&response);
  LSErrorFree(&lserror);

  return returnVal;
}
Example #29
0
/*
** Impl of /json/dir. 98% of it was taken directly
** from browse.c::page_dir()
*/
static cson_value * json_page_dir_list(){
  cson_object * zPayload = NULL; /* return value */
  cson_array * zEntries = NULL; /* accumulated list of entries. */
  cson_object * zEntry = NULL;  /* a single dir/file entry. */
  cson_array * keyStore = NULL; /* garbage collector for shared strings. */
  cson_string * zKeyName = NULL;
  cson_string * zKeySize = NULL;
  cson_string * zKeyIsDir = NULL;
  cson_string * zKeyUuid = NULL;
  cson_string * zKeyTime = NULL;
  cson_string * zKeyRaw = NULL;
  char * zD = NULL;
  char const * zDX = NULL;
  int nD;
  char * zUuid = NULL;
  char const * zCI = NULL;
  Manifest * pM = NULL;
  Stmt q = empty_Stmt;
  int rid = 0;
  if( !g.perm.Read ){
    json_set_err(FSL_JSON_E_DENIED, "Requires 'o' permissions.");
    return NULL;
  }
  zCI = json_find_option_cstr("checkin",NULL,"ci" );

  /* If a specific check-in is requested, fetch and parse it.  If the
  ** specific check-in does not exist, clear zCI.  zCI==0 will cause all
  ** files from all check-ins to be displayed.
  */
  if( zCI && *zCI ){
    pM = manifest_get_by_name(zCI, &rid);
    if( pM ){
      zUuid = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", rid);
    }else{
      json_set_err(FSL_JSON_E_UNRESOLVED_UUID,
                   "Checkin name [%s] is unresolved.",
                   zCI);
      return NULL;
    }
  }

  /* Jump through some hoops to find the directory name... */
  zDX = json_find_option_cstr("name",NULL,NULL);
  if(!zDX && !g.isHTTP){
    zDX = json_command_arg(g.json.dispatchDepth+1);
  }
  if(zDX && (!*zDX || (0==strcmp(zDX,"/")))){
    zDX = NULL;
  }
  zD = zDX ? fossil_strdup(zDX) : NULL;
  nD = zD ? strlen(zD)+1 : 0;
  while( nD>1 && zD[nD-2]=='/' ){ zD[(--nD)-1] = 0; }

  sqlite3_create_function(g.db, "pathelement", 2, SQLITE_UTF8, 0,
                          pathelementFunc, 0, 0);

  /* Compute the temporary table "localfiles" containing the names
  ** of all files and subdirectories in the zD[] directory.
  **
  ** Subdirectory names begin with "/".  This causes them to sort
  ** first and it also gives us an easy way to distinguish files
  ** from directories in the loop that follows.
  */

  if( zCI ){
    Stmt ins;
    ManifestFile *pFile;
    ManifestFile *pPrev = 0;
    int nPrev = 0;
    int c;

    db_multi_exec(
                  "CREATE TEMP TABLE json_dir_files("
                  "  n UNIQUE NOT NULL," /* file name */
                  "  fn UNIQUE NOT NULL," /* full file name */
                  "  u DEFAULT NULL," /* file uuid */
                  "  sz DEFAULT -1," /* file size */
                  "  mtime DEFAULT NULL" /* file mtime in unix epoch format */
                  ");"
                  );

    db_prepare(&ins,
               "INSERT OR IGNORE INTO json_dir_files (n,fn,u,sz,mtime) "
               "SELECT"
               "  pathelement(:path,0),"
               "  CASE WHEN %Q IS NULL THEN '' ELSE %Q||'/' END ||:abspath,"
               "  a.uuid,"
               "  a.size,"
               "  CAST(strftime('%%s',e.mtime) AS INTEGER) "
               "FROM"
               "  mlink m, "
               "  event e,"
               "  blob a,"
               "  blob b "
               "WHERE"
               " e.objid=m.mid"
               " AND a.rid=m.fid"/*FILE artifact*/
               " AND b.rid=m.mid"/*CHECKIN artifact*/
               " AND a.uuid=:uuid",
               zD, zD
               );
    manifest_file_rewind(pM);
    while( (pFile = manifest_file_next(pM,0))!=0 ){
      if( nD>0
        && ((pFile->zName[nD-1]!='/') || (0!=memcmp(pFile->zName, zD, nD-1)))
      ){
        continue;
      }
      /*printf("zD=%s, nD=%d, pFile->zName=%s\n", zD, nD, pFile->zName);*/
      if( pPrev
       && memcmp(&pFile->zName[nD],&pPrev->zName[nD],nPrev)==0
       && (pFile->zName[nD+nPrev]==0 || pFile->zName[nD+nPrev]=='/')
      ){
        continue;
      }
      db_bind_text( &ins, ":path", &pFile->zName[nD] );
      db_bind_text( &ins, ":abspath", &pFile->zName[nD] );
      db_bind_text( &ins, ":uuid", pFile->zUuid );
      db_step(&ins);
      db_reset(&ins);
      pPrev = pFile;
      for(nPrev=0; (c=pPrev->zName[nD+nPrev]) && c!='/'; nPrev++){}
      if( c=='/' ) nPrev++;
    }
    db_finalize(&ins);
  }else if( zD && *zD ){
    db_multi_exec(
      "CREATE TEMP VIEW json_dir_files AS"
      " SELECT DISTINCT(pathelement(name,%d)) AS n,"
      " %Q||'/'||name AS fn,"
      " NULL AS u, NULL AS sz, NULL AS mtime"
      " FROM filename"
      "  WHERE name GLOB '%q/*'"
      " GROUP BY n",
      nD, zD, zD
    );
  }else{
    db_multi_exec(
      "CREATE TEMP VIEW json_dir_files"
      " AS SELECT DISTINCT(pathelement(name,0)) AS n, NULL AS fn"
      " FROM filename"
    );
  }

  if(zCI){
    db_prepare( &q, "SELECT"
                "  n as name,"
                "  fn as fullname,"
                "  u as uuid,"
                "  sz as size,"
                "  mtime as mtime "
                "FROM json_dir_files ORDER BY n");
  }else{/* UUIDs are all NULL. */
    db_prepare( &q, "SELECT n, fn FROM json_dir_files ORDER BY n");
  }

  zKeyName = cson_new_string("name",4);
  zKeyUuid = cson_new_string("uuid",4);
  zKeyIsDir = cson_new_string("isDir",5);
  keyStore = cson_new_array();
  cson_array_append( keyStore, cson_string_value(zKeyName) );
  cson_array_append( keyStore, cson_string_value(zKeyUuid) );
  cson_array_append( keyStore, cson_string_value(zKeyIsDir) );

  if( zCI ){
    zKeySize = cson_new_string("size",4);
    cson_array_append( keyStore, cson_string_value(zKeySize) );
    zKeyTime = cson_new_string("timestamp",9);
    cson_array_append( keyStore, cson_string_value(zKeyTime) );
    zKeyRaw = cson_new_string("downloadPath",12);
    cson_array_append( keyStore, cson_string_value(zKeyRaw) );
  }
  zPayload = cson_new_object();
  cson_object_set_s( zPayload, zKeyName,
                     json_new_string((zD&&*zD) ? zD : "/") );
  if( zUuid ){
    cson_object_set( zPayload, "checkin", json_new_string(zUuid) );
  }

  while( (SQLITE_ROW==db_step(&q)) ){
    cson_value * name = NULL;
    char const * n = db_column_text(&q,0);
    char const isDir = ('/'==*n);
    zEntry = cson_new_object();
    if(!zEntries){
      zEntries = cson_new_array();
      cson_object_set( zPayload, "entries", cson_array_value(zEntries) );
    }
    cson_array_append(zEntries, cson_object_value(zEntry) );
    if(isDir){
      name = json_new_string( n+1 );
      cson_object_set_s(zEntry, zKeyIsDir, cson_value_true() );
    } else{
      name = json_new_string( n );
    }
    cson_object_set_s(zEntry, zKeyName, name );
    if( zCI && !isDir){
      /* Don't add the uuid/size for dir entries - that data refers to
         one of the files in that directory :/. Entries with no
         --checkin may refer to N versions, and therefore we cannot
         associate a single size and uuid with them (and fetching all
         would be overkill for most use cases).
      */
      char const * fullName = db_column_text(&q,1);
      char const * u = db_column_text(&q,2);
      sqlite_int64 const sz = db_column_int64(&q,3);
      sqlite_int64 const ts = db_column_int64(&q,4);
      cson_object_set_s(zEntry, zKeyUuid, json_new_string( u ) );
      cson_object_set_s(zEntry, zKeySize,
                        cson_value_new_integer( (cson_int_t)sz ));
      cson_object_set_s(zEntry, zKeyTime,
          cson_value_new_integer( (cson_int_t)ts ));
      cson_object_set_s(zEntry, zKeyRaw,
                        json_new_string_f("/raw/%T?name=%t",
                                          fullName, u));
    }
  }
  db_finalize(&q);
  if(pM){
    manifest_destroy(pM);
  }
  cson_free_array( keyStore );

  free( zUuid );
  free( zD );
  return cson_object_value(zPayload);
}
bool list_method(LSHandle* lshandle, LSMessage *message, void *ctx) {

  bool returnVal = true;
  char line[MAXLINELEN];
  // %%% MAGIC NUMBERS ALERT %%%
  char name[128];
  char state[16];
  char status[128];

  LSError lserror;
  LSErrorInit(&lserror);

  char *jsonResponse = 0;
  int len = 0;

  json_t *response = json_new_object();

  FILE *fp = popen("/sbin/initctl list", "r");
  if (fp) {
    json_t *array = json_new_array();
    while ( fgets( line, sizeof line, fp)) {
      // %%% MAGIC NUMBERS ALERT %%%
      if (sscanf(line, "%127s (start) %127c",
		 (char*)&name, (char *)&status) == 2) {
	// %%% HACK ALERT %%%
	*strchr(status,'\n') = 0;
	json_t *object = json_new_object();
	// %%% IGNORING RETURN ALERT %%%
	json_insert_pair_into_object(object, "name", json_new_string(name));
	json_insert_pair_into_object(object, "state", json_new_string("start"));
	json_insert_pair_into_object(object, "status", json_new_string(status));
	json_insert_child(array, object);
      }
      // %%% MAGIC NUMBERS ALERT %%%
      else if (sscanf(line, "%127s (stop) %127c",
		 (char*)&name, (char *)&status) == 2) {
	// %%% HACK ALERT %%%
	*strchr(status,'\n') = 0;
	json_t *object = json_new_object();
	// %%% IGNORING RETURN ALERT %%%
	json_insert_pair_into_object(object, "name", json_new_string(name));
	json_insert_pair_into_object(object, "state", json_new_string("stop"));
	json_insert_pair_into_object(object, "status", json_new_string(status));
	json_insert_child(array, object);
      }
    }
    if (!pclose(fp)) {
      // %%% IGNORING RETURN ALERT %%%
      json_insert_pair_into_object(response, "returnValue", json_new_true());
      json_insert_pair_into_object(response, "jobs", array);
      json_tree_to_string(response, &jsonResponse);
    }
  }

  if (jsonResponse) {
    LSMessageReply(lshandle, message, jsonResponse, &lserror);
    free(jsonResponse);
  } else
    LSMessageReply(lshandle, message, "{\"returnValue\":false,\"errorCode\":-1,\"errorText\":\"Generic error\"}", &lserror);
 
  json_free_value(&response);
  LSErrorFree(&lserror);

  return returnVal;
}