void on_started (struct tgl_state *TLS) { if (wait_dialog_list) { wait_dialog_list = 0; tgl_do_get_dialog_list (TLS, 100, 0, dlist_cb, 0); return; } #ifdef USE_LUA lua_diff_end (); #endif #ifdef USE_PYTHON py_diff_end (); #endif if (start_command) { safe_quit = 1; while (*start_command) { char *start = start_command; while (*start_command && *start_command != '\n') { start_command ++; } if (*start_command) { *start_command = 0; start_command ++; } interpreter_ex (start, 0); } } }
void tw_do_get_dialog_list (struct tgl_state *TLS, void (*callback)(struct tgl_state *TLS, int success, int size, tgl_peer_id_t peers[], int last_msg_id[], int unread_count[], void* data), void *callback_extra) { callback_data* data = (callback_data*) malloc (sizeof (callback_data)); assert (data); data->callback = callback; data->data = callback_extra; tgl_do_get_dialog_list (TLS, tw_get_dialog_list_cb, data); }
void on_ready (struct tgl_state *TLS) { debug ("on_ready().\n"); telegram_conn *conn = TLS->ev_base; purple_connection_set_state(conn->gc, PURPLE_CONNECTED); purple_connection_set_display_name(conn->gc, purple_account_get_username(conn->pa)); purple_blist_add_account(conn->pa); tggroup = purple_find_group("Telegram"); if (tggroup == NULL) { debug ("PurpleGroup = NULL, creating"); tggroup = purple_group_new ("Telegram"); purple_blist_add_group (tggroup, NULL); } debug ("seq = %d, pts = %d\n", TLS->seq, TLS->pts); tgl_do_get_difference (TLS, 0, 0, 0); tgl_do_get_dialog_list (TLS, 0, 0); tgl_do_update_contact_list (TLS, 0, 0); conn->timer = purple_timeout_add (5000, queries_timerfunc, conn); }
void py_do_all (void) { int p = 0; while (p < pos) { assert (p + 2 <= pos); enum py_query_type f = (long)py_ptr[p ++]; PyObject *args = (PyObject *)py_ptr[p ++]; const char *str, *str1, *str2, *str3; Py_ssize_t i; tgl_user_id_t *ids; int len, len1, len2, len3; int limit, offset; long msg_id = 0; PyObject *pyObj1 = NULL; PyObject *pyObj2 = NULL; PyObject *cb_extra = NULL; PyObject *peer = NULL; PyObject *peer1 = NULL; switch (f) { case pq_contact_list: if(PyArg_ParseTuple(args, "|O", &cb_extra)) tgl_do_update_contact_list (TLS, py_contact_list_cb, cb_extra); else PyErr_Print(); break; case pq_dialog_list: if(PyArg_ParseTuple(args, "|O", &cb_extra)) tgl_do_get_dialog_list (TLS, 100, 0, py_dialog_list_cb, cb_extra); else PyErr_Print(); break; case pq_msg: if(PyArg_ParseTuple(args, "O!s#|O", &tgl_PeerType, &peer, &str, &len, &cb_extra)) tgl_do_send_message (TLS, PY_PEER_ID(peer), str, len, 0, py_msg_cb, cb_extra); else PyErr_Print(); break; case pq_send_typing: if(PyArg_ParseTuple(args, "O!|O", &tgl_PeerType, &peer, &cb_extra)) tgl_do_send_typing (TLS, PY_PEER_ID(peer), tgl_typing_typing, py_empty_cb, cb_extra); else PyErr_Print(); break; case pq_send_typing_abort: if(PyArg_ParseTuple(args, "O!|O", &tgl_PeerType, &peer, &cb_extra)) tgl_do_send_typing (TLS, PY_PEER_ID(peer), tgl_typing_cancel, py_empty_cb, cb_extra); else PyErr_Print(); break; case pq_rename_chat: if(PyArg_ParseTuple(args, "O!s#|O", &tgl_PeerType, &peer, &str, &len, &cb_extra)) tgl_do_rename_chat (TLS, PY_PEER_ID(peer), str, len, py_empty_cb, cb_extra); else PyErr_Print(); break; case pq_send_photo: if(PyArg_ParseTuple(args, "O!s|O", &tgl_PeerType, &peer, &str, &cb_extra)) tgl_do_send_document (TLS, PY_PEER_ID(peer), str, NULL, 0, TGL_SEND_MSG_FLAG_DOCUMENT_PHOTO, py_msg_cb, cb_extra); else PyErr_Print(); break; case pq_send_video: if(PyArg_ParseTuple(args, "O!s|O", &tgl_PeerType, &peer, &str, &cb_extra)) tgl_do_send_document (TLS, PY_PEER_ID(peer), str, NULL, 0, TGL_SEND_MSG_FLAG_DOCUMENT_VIDEO, py_msg_cb, cb_extra); else PyErr_Print(); break; case pq_send_audio: if(PyArg_ParseTuple(args, "O!s|O", &tgl_PeerType, &peer, &str, &cb_extra)) tgl_do_send_document (TLS, PY_PEER_ID(peer), str, NULL, 0, TGL_SEND_MSG_FLAG_DOCUMENT_AUDIO, py_msg_cb, cb_extra); else PyErr_Print(); break; case pq_send_document: if(PyArg_ParseTuple(args, "O!s|O", &tgl_PeerType, &peer, &str, &cb_extra)) tgl_do_send_document (TLS, PY_PEER_ID(peer), str, NULL, 0, 0, py_msg_cb, cb_extra); else PyErr_Print(); break; case pq_send_file: if(PyArg_ParseTuple(args, "O!s|O", &tgl_PeerType, &peer, &str, &cb_extra)) tgl_do_send_document (TLS, PY_PEER_ID(peer), str, NULL, 0, TGL_SEND_MSG_FLAG_DOCUMENT_AUTO, py_msg_cb, cb_extra); else PyErr_Print(); break; case pq_send_text: if(PyArg_ParseTuple(args, "O!s|O", &tgl_PeerType, &peer, &str, &cb_extra)) tgl_do_send_text (TLS, PY_PEER_ID(peer), str, 0, py_msg_cb, cb_extra); else PyErr_Print(); break; case pq_chat_set_photo: if(PyArg_ParseTuple(args, "O!s|O", &tgl_PeerType, &peer, &str, &cb_extra)) tgl_do_set_chat_photo (TLS, PY_PEER_ID(peer), str, py_empty_cb, cb_extra); else PyErr_Print(); break; /* case pq_load_photo: case pq_load_video: case pq_load_audio: case pq_load_document: M = py_ptr[p + 1]; if (!M || (M->media.type != tgl_message_media_photo && M->media.type != tgl_message_media_photo_encr && M->media.type != tgl_message_media_document && M->media.type != tgl_message_media_document_encr)) { py_file_cb (TLS, py_ptr[p], 0, 0); } else { , limit, offse, limit, offsettif (M->media.type == tgl_message_media_photo) { tgl_do_load_photo (TLS, &M->media.photo, py_file_cb, py_ptr[p]); } else if (M->media.type == tgl_message_media_document) { tgl_do_load_document (TLS, &M->media.document, py_file_cb, py_ptr[p]); } else { tgl_do_load_encr_document (TLS, &M->media.encr_document, py_file_cb, py_ptr[p]); } } break; case pq_load_video_thumb: case pq_load_document_thumb: M = py_ptr[p + 1]; if (!M || (M->media.type != tgl_message_media_document)) { py_file_cb (TLS, py_ptr[p], 0, 0); } else { tgl_do_load_document_thumb (TLS, &M->media.document, py_file_cb, py_ptr[p]); } break; */ case pq_fwd: if(PyArg_ParseTuple(args, "O!l|O", &tgl_PeerType, &peer, &msg_id, &cb_extra)) tgl_do_forward_message (TLS, PY_PEER_ID(peer), msg_id, 0, py_msg_cb, cb_extra); else PyErr_Print(); break; case pq_fwd_media: if(PyArg_ParseTuple(args, "O!l|O", &tgl_PeerType, &peer, &msg_id, &cb_extra)) tgl_do_forward_media (TLS, PY_PEER_ID(peer), msg_id, 0, py_msg_cb, cb_extra); else PyErr_Print(); break; case pq_chat_info: if(PyArg_ParseTuple(args, "O!|O", &tgl_PeerType, &peer, &cb_extra)) tgl_do_get_chat_info (TLS, PY_PEER_ID(peer), 0, py_chat_cb, cb_extra); else PyErr_Print(); break; case pq_user_info: if(PyArg_ParseTuple(args, "O!|O", &tgl_PeerType, &peer, &cb_extra)) tgl_do_get_user_info (TLS, PY_PEER_ID(peer), 0, py_user_cb, cb_extra); else PyErr_Print(); break; case pq_history: if(PyArg_ParseTuple(args, "O!ii|O", &tgl_PeerType, &peer, &offset, &limit, &cb_extra)) tgl_do_get_history (TLS, PY_PEER_ID(peer), offset, limit, 0, py_msg_list_cb, cb_extra); else PyErr_Print(); break; case pq_chat_add_user: if(PyArg_ParseTuple(args, "O!O!|O", &tgl_PeerType, &peer, &tgl_PeerType, &peer1, &cb_extra)) tgl_do_add_user_to_chat (TLS, PY_PEER_ID(peer), PY_PEER_ID(peer1), 100, py_empty_cb, cb_extra); else PyErr_Print(); break; case pq_chat_del_user: if(PyArg_ParseTuple(args, "O!O!|O", &tgl_PeerType, &peer, &tgl_PeerType, &peer1, &cb_extra)) tgl_do_del_user_from_chat (TLS, PY_PEER_ID(peer), PY_PEER_ID(peer1), py_empty_cb, cb_extra); else PyErr_Print(); break; case pq_add_contact: if(PyArg_ParseTuple(args, "s#s#s#|O", &str1, &len1, &str2, &len2, &str3, &len3, &cb_extra)) tgl_do_add_contact (TLS, str1, len1, str2, len2, str3, len3, 0, py_contact_list_cb, cb_extra); else PyErr_Print(); break; case pq_del_contact: if(PyArg_ParseTuple(args, "O!|O", &tgl_PeerType, &peer, &cb_extra)) tgl_do_del_contact (TLS, PY_PEER_ID(peer), py_empty_cb, cb_extra); else PyErr_Print(); break; case pq_rename_contact: if(PyArg_ParseTuple(args, "s#s#s#|O", &str1, &len1, &str2, &len2, &str3, &len3, &cb_extra)) tgl_do_add_contact (TLS, str1, len1, str2, len2, str3, len3, 1, py_contact_list_cb, cb_extra); else PyErr_Print(); break; case pq_search: if(PyArg_ParseTuple(args, "O!s#|O", &tgl_PeerType, &peer, &str, &len, &cb_extra)) tgl_do_msg_search (TLS, PY_PEER_ID(peer), 0, 0, 40, 0, str, len, py_msg_list_cb, cb_extra); else PyErr_Print(); break; case pq_global_search: if(PyArg_ParseTuple(args, "s#|O", &str, &len, &cb_extra)) tgl_do_msg_search (TLS, tgl_set_peer_id (TGL_PEER_UNKNOWN, 0), 0, 0, 40, 0, str, len, py_msg_list_cb, cb_extra); else PyErr_Print(); break; case pq_mark_read: if(PyArg_ParseTuple(args, "O!|O", &tgl_PeerType, &peer, &cb_extra)) tgl_do_mark_read (TLS, PY_PEER_ID(peer), py_empty_cb, cb_extra); else PyErr_Print(); break; case pq_set_profile_photo: if(PyArg_ParseTuple(args, "s|O", &str, &cb_extra)) tgl_do_set_profile_photo (TLS, str, py_empty_cb, cb_extra); else PyErr_Print(); break; case pq_set_profile_name: if(PyArg_ParseTuple(args, "s#s#|O", &str1, &len1, &str2, &len2, &cb_extra)) tgl_do_set_profile_name (TLS, str1, len1, str2, len2, py_user_cb, cb_extra); else PyErr_Print(); break; case pq_create_secret_chat: if(PyArg_ParseTuple(args, "O!|O", &tgl_PeerType, &peer, &cb_extra)) tgl_do_create_secret_chat (TLS, PY_PEER_ID(peer), py_secret_chat_cb, cb_extra); else PyErr_Print(); break; case pq_create_group_chat: if(PyArg_ParseTuple(args, "O!s#|O", &PyList_Type, &pyObj1, &str, &len, &cb_extra)) { if(PyList_GET_SIZE(pyObj1) > 2) { ids = (tgl_user_id_t *)malloc(PyList_GET_SIZE(pyObj1) * sizeof(tgl_user_id_t)); for(i = 0; i < PyList_GET_SIZE(pyObj1); i++) { peer = PyList_GetItem(pyObj1, i); *(ids+i) = PY_PEER_ID(peer); } tgl_do_create_group_chat (TLS, PyList_GET_SIZE(pyObj1), ids, str, len, py_empty_cb, cb_extra); tfree(ids, PyList_GET_SIZE(pyObj1) * sizeof(tgl_user_id_t)); } else { logprintf("create_group_chat: Argument 1 must be a list of at least 3 peers"); } } Py_XDECREF(pyObj1); break; case pq_delete_msg: case pq_restore_msg: if(PyArg_ParseTuple(args, "l|O", &msg_id, &cb_extra)) tgl_do_delete_msg (TLS, msg_id, py_empty_cb, cb_extra); else PyErr_Print(); break; /* case pq_accept_secret_chat: tgl_do_accept_encr_chat_request (TLS, py_ptr[p + 1], py_secret_chat_cb, py_ptr[p]); break; */ case pq_send_contact: if(PyArg_ParseTuple(args, "O!s#s#s#|O", &tgl_PeerType, &peer, &str1, &len1, &str2, &len2, &str3, &len3, &cb_extra)) tgl_do_send_contact (TLS, PY_PEER_ID(peer), str1, len1, str2, len2, str3, len3, 0, py_msg_cb, cb_extra); else PyErr_Print(); break; case pq_status_online: if(PyArg_ParseTuple(args, "|O", &cb_extra)) tgl_do_update_status (TLS, 1, py_empty_cb, cb_extra); else PyErr_Print(); break; case pq_status_offline: if(PyArg_ParseTuple(args, "|O", &cb_extra)) tgl_do_update_status (TLS, 0, py_empty_cb, cb_extra); else PyErr_Print(); break; case pq_extf: if(PyArg_ParseTuple(args, "s#|O", &str, &len, &cb_extra)) tgl_do_send_extf (TLS, str, len, py_str_cb, &cb_extra); else PyErr_Print(); break; case pq_send_location: if(PyArg_ParseTuple(args, "O!O!O!|O", &tgl_PeerType, &peer, &PyFloat_Type, &pyObj1, &PyFloat_Type, &pyObj2, &cb_extra)) { tgl_do_send_location (TLS, PY_PEER_ID(peer), PyFloat_AsDouble(pyObj1), PyFloat_AsDouble(pyObj2), 0, py_msg_cb, cb_extra); Py_XDECREF(pyObj1); Py_XDECREF(pyObj2); } else PyErr_Print(); break; default: assert (0); } // Increment reference on cb_extra as it is passed on to the callback to use Py_XINCREF(cb_extra); // Clean up any arg variables we could have used. //Py_XDECREF(args); // TODO: this is going negative ref and causing segfaults Py_XDECREF(peer); Py_XDECREF(peer1); } pos = 0; }
int loop (void) { //on_start (); tgl_set_callback (TLS, &upd_cb); //TLS->temp_key_expire_time = 60; struct event_base *ev = event_base_new (); tgl_set_ev_base (TLS, ev); tgl_set_net_methods (TLS, &tgl_conn_methods); tgl_set_timer_methods (TLS, &tgl_libevent_timers); assert (TLS->timer_methods); tgl_set_download_directory (TLS, get_downloads_directory ()); tgl_register_app_id (TLS, TELEGRAM_CLI_APP_ID, TELEGRAM_CLI_APP_HASH); tgl_init (TLS); if (binlog_enabled) { double t = tglt_get_double_time (); if (verbosity >= E_DEBUG) { logprintf ("replay log start\n"); } tgl_replay_log (TLS); if (verbosity >= E_DEBUG) { logprintf ("replay log end in %lf seconds\n", tglt_get_double_time () - t); } tgl_reopen_binlog_for_writing (TLS); } else { read_auth_file (); read_state_file (); read_secret_chat_file (); } binlog_read = 1; #ifdef USE_LUA lua_binlog_end (); #endif if (sfd >= 0) { struct event *ev = event_new (TLS->ev_base, sfd, EV_READ | EV_PERSIST, accept_incoming, 0); event_add (ev, 0); } if (usfd >= 0) { struct event *ev = event_new (TLS->ev_base, usfd, EV_READ | EV_PERSIST, accept_incoming, 0); event_add (ev, 0); } update_prompt (); if (reset_authorization) { tgl_peer_t *P = tgl_peer_get (TLS, TGL_MK_USER (TLS->our_id)); if (P && P->user.phone && reset_authorization == 1) { set_default_username (P->user.phone); } bl_do_reset_authorization (TLS); } net_loop (0, all_authorized); int i; for (i = 0; i <= TLS->max_dc_num; i++) if (TLS->DC_list[i] && !tgl_authorized_dc (TLS, TLS->DC_list[i])) { assert (0); } if (!tgl_signed_dc (TLS, TLS->DC_working)) { if (disable_output) { fprintf (stderr, "Can not login without output\n"); do_halt (1); } if (!default_username) { size_t size = 0; char *user = 0; if (!user) { printf ("Telephone number (with '+' sign): "); if (net_getline (&user, &size) == -1) { perror ("getline()"); do_halt (1); } set_default_username (user); } } tgl_do_send_code (TLS, default_username, sign_in_callback, 0); net_loop (0, sent_code); if (verbosity >= E_DEBUG) { logprintf ("%s\n", should_register ? "phone not registered" : "phone registered"); } if (!should_register) { char *code = 0; size_t size = 0; printf ("Code from sms (if you did not receive an SMS and want to be called, type \"call\"): "); while (1) { if (net_getline (&code, &size) == -1) { perror ("getline()"); do_halt (1); } if (!strcmp (code, "call")) { printf ("You typed \"call\", switching to phone system.\n"); tgl_do_phone_call (TLS, default_username, hash, 0, 0); printf ("Calling you! Code: "); continue; } if (tgl_do_send_code_result (TLS, default_username, hash, code, sign_in_result, 0) >= 0) { break; } printf ("Invalid code. Try again: "); free (code); } } else { printf ("User is not registered. Do you want to register? [Y/n] "); char *code; size_t size; if (net_getline (&code, &size) == -1) { perror ("getline()"); do_halt (1); } if (!*code || *code == 'y' || *code == 'Y') { printf ("Ok, starting registartion.\n"); } else { printf ("Then try again\n"); do_halt (1); } char *first_name; printf ("First name: "); if (net_getline (&first_name, &size) == -1) { perror ("getline()"); do_halt (1); } char *last_name; printf ("Last name: "); if (net_getline (&last_name, &size) == -1) { perror ("getline()"); do_halt (1); } printf ("Code from sms (if you did not receive an SMS and want to be called, type \"call\"): "); while (1) { if (net_getline (&code, &size) == -1) { perror ("getline()"); do_halt (1); } if (!strcmp (code, "call")) { printf ("You typed \"call\", switching to phone system.\n"); tgl_do_phone_call (TLS, default_username, hash, 0, 0); printf ("Calling you! Code: "); continue; } if (tgl_do_send_code_result_auth (TLS, default_username, hash, code, first_name, last_name, sign_in_result, 0) >= 0) { break; } printf ("Invalid code. Try again: "); free (code); } } net_loop (0, signed_in); //bl_do_dc_signed (TLS->DC_working); } for (i = 0; i <= TLS->max_dc_num; i++) if (TLS->DC_list[i] && !tgl_signed_dc (TLS, TLS->DC_list[i])) { tgl_do_export_auth (TLS, i, export_auth_callback, (void*)(long)TLS->DC_list[i]); cur_a_dc = TLS->DC_list[i]; net_loop (0, dc_signed_in); assert (tgl_signed_dc (TLS, TLS->DC_list[i])); } write_auth_file (); fflush (stdout); fflush (stderr); //read_state_file (); //read_secret_chat_file (); set_interface_callbacks (); tglm_send_all_unsent (TLS); tgl_do_get_difference (TLS, sync_from_start, get_difference_callback, 0); net_loop (0, dgot); assert (!(TLS->locks & TGL_LOCK_DIFF)); TLS->started = 1; if (wait_dialog_list) { d_got_ok = 0; tgl_do_get_dialog_list (TLS, dlist_cb, 0); net_loop (0, dgot); } #ifdef USE_LUA lua_diff_end (); #endif if (start_command) { safe_quit = 1; while (*start_command) { char *start = start_command; while (*start_command && *start_command != '\n') { start_command ++; } if (*start_command) { *start_command = 0; start_command ++; } interpreter_ex (start, 0); } } /*tgl_do_get_dialog_list (get_dialogs_callback, 0); if (wait_dialog_list) { dialog_list_got = 0; net_loop (0, dlgot); }*/ return main_loop (); }