static mp_net_stream_packet_t* send_net_stream_cmd(stream_t *s,uint16_t cmd,char* data,int len) { mp_net_stream_packet_t* pack; // Cache is enabled : lock if(s->cache_data && !lock_fd(s->fd)) return NULL; // Send a command if(!write_packet(s->fd,cmd,data,len)) { if(s->cache_data) unlock_fd(s->fd); return 0; } // Read the response pack = read_packet(s->fd); // Now we can unlock if(s->cache_data) unlock_fd(s->fd); if(!pack) return NULL; switch(pack->cmd) { case NET_STREAM_OK: return pack; case NET_STREAM_ERROR: if(pack->len > sizeof(mp_net_stream_packet_t)) mp_msg(MSGT_STREAM,MSGL_ERR, "Fill buffer failed: %s\n",pack->data); else mp_msg(MSGT_STREAM,MSGL_ERR, "Fill buffer failed\n"); free(pack); return NULL; } mp_msg(MSGT_STREAM,MSGL_ERR, "Unknown response to %d: %d\n",cmd,pack->cmd); free(pack); return NULL; }
static void update_log(const struct toptenentry *newtt) { /* used for debugging (who dies of what, where) */ int fd = open_datafile(LOGFILE, O_CREAT | O_APPEND | O_WRONLY, SCOREPREFIX); if (lock_fd(fd, 10)) { writeentry(fd, newtt); unlock_fd(fd); close(fd); } }
static void update_xlog(const struct toptenentry *newtt) { /* used for statistical purposes and tournament scoring */ int fd = open_datafile(XLOGFILE, O_CREAT | O_APPEND | O_WRONLY, SCOREPREFIX); if (lock_fd(fd, 10)) { FILE *xlfile = fdopen(fd, "a"); write_xlentry(xlfile, newtt); unlock_fd(fd); fclose(xlfile); /* also closes fd */ } }
int ReOpenConnection(stream_t* s) { //printf("Reopening connection\n");fflush(stdout); struct stream_priv_s* p = (struct stream_priv_s*)s->priv; if (!p->url) return 0; unlock_fd(p); close(s->fd); s->fd = 0; if (OpenConnection(s)) { lock_fd(p); return 1; } return 0; }
static int do_service(void) { int rc; rc = dbus_bus_request_name(connection, name, DBUS_NAME_FLAG_REPLACE_EXISTING, &error); if (dbus_error_is_set(&error)) { fprintf(stderr, "FAIL: %s: %s\n", error.name, error.message); dbus_error_free(&error); } if (rc != DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER) { return 1; } if (unlock_fd()) return 1; rc = 0; while (!terminate && !rc) rc = handle_messages(); /* If we've received SIGTERM, try one last time to drain the incoming queue */ if (terminate && !rc) rc = handle_messages(); if (rc < 0) return 1; rc = dbus_bus_release_name(connection, name, &error); if (dbus_error_is_set(&error)) { fprintf(stderr, "FAIL: %s: %s\n", error.name, error.message); dbus_error_free(&error); } if (rc != DBUS_RELEASE_NAME_REPLY_RELEASED) { return 1; } return 0; }
/* * Add the result of the current game to the score list */ void update_topten(int how) { struct toptenentry *toptenlist, newtt; boolean need_rewrite; int fd; if (program_state.panicking) return; end_how = how; /* save how for nh_get_topten */ fill_topten_entry(&newtt, how); update_log(&newtt); update_xlog(&newtt); /* nothing more to do for non-scoring games */ if (wizard || discover) return; fd = open_datafile(RECORD, O_RDWR | O_CREAT, SCOREPREFIX); if (!lock_fd(fd, 30)) { close(fd); return; } toptenlist = read_topten(fd, TTLISTLEN); /* possibly rearrange the score list to include the new entry */ need_rewrite = toptenlist_insert(toptenlist, &newtt); if (need_rewrite) write_topten(fd, toptenlist); unlock_fd(fd); close(fd); free(toptenlist); }
int unlock_file(FILE *f) { assert(f); return unlock_fd(fileno(f)); }
int main(int argc, char *argv[]) { int i, rc; if (argc < 3) { usage(); rc = 1; goto out; } rc = setup_signal_handling(); if (rc != 0) { fprintf(stderr, "FAIL: Couldn't set up signal handler\n"); rc = 1; goto out; } for (i = 1; i < argc && interface == NULL; i++) { char *arg = argv[i]; if (strcmp(arg, "--system") == 0) { type = DBUS_BUS_SYSTEM; session_or_system = TRUE; } else if (strcmp(arg, "--session") == 0) { type = DBUS_BUS_SESSION; session_or_system = TRUE; } else if (strstr(arg, "--address") == arg) { address = strchr(arg, '='); if (address == NULL) { fprintf(stderr, "FAIL: \"--address=\" requires an ADDRESS\n"); usage(); rc = 1; goto out; } else { address = address + 1; } } else if (strstr(arg, "--name=") == arg) name = strchr(arg, '=') + 1; else if (strstr(arg, "--log=") == arg) { char *path = strchr(arg, '=') + 1; log_fd = open(path, O_CREAT | O_TRUNC | O_WRONLY, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH); if (log_fd < 0) { fprintf(stderr, "FAIL: Couldn't open log file \"%s\"\n", path); exit(1); } } else if (strstr(arg, "--lock-fd=") == arg) { char *fd = strchr(arg, '=') + 1; lock_fd = atoi(fd); } else if (!strcmp(arg, "--help")) { usage(); rc = 0; goto out; } else if (arg[0] == '-') { usage(); rc = 1; goto out; } else if (path == NULL) path = arg; else /* interface == NULL guaranteed by the 'while' loop */ interface = arg; } if (name == NULL || path == NULL || interface == NULL || i < argc) { usage(); rc = 1; goto out; } if (session_or_system && (address != NULL)) { fprintf(stderr, "FAIL: \"--address\" may not be used with \"--system\" or \"--session\"\n"); usage(); rc = 1; goto out; } dbus_error_init(&error); if (address != NULL) connection = dbus_connection_open(address, &error); else connection = dbus_bus_get(type, &error); if (connection == NULL) { fprintf(stderr, "FAIL: Failed to open connection to \"%s\" message bus: %s\n", address ? address : ((type == DBUS_BUS_SYSTEM) ? "system" : "session"), error.message); dbus_error_free(&error); rc = 1; goto out; } else if (address != NULL) dbus_bus_register(connection, &error); rc = do_service(); out: if (connection) dbus_connection_unref(connection); unlock_fd(); if (rc == 0) printf("PASS\n"); exit(rc); }
static int fill_buffer(stream_t *s, char* pbBuffer, int max_len) { struct stream_priv_s* p = (struct stream_priv_s*)s->priv; // Check on EOS condition if (s->activeFileFlag) p->actualSize = 0; if (!p->actualSize && !s->activeFileFlag) { // Get the actual size and store it p->actualSize = size(s, NULL); } if (p->actualSize && !s->activeFileFlag) { if (max_len + s->pos > p->actualSize) { max_len = p->actualSize - s->pos; if (max_len < 0) max_len = 0; } } if (max_len <= 0) return 0; char data[512]; lock_fd(p); #ifndef WIN32 sprintf(data, "READ %lld %d\r\n", s->pos, max_len); #else sprintf(data, "READ %I64d %d\r\n", s->pos, max_len); #endif int dataSize = strlen(data); //printf("Sending cmd to SageTV Server:%s\n", data);fflush(stdout); if (send(s->fd, data, dataSize, 0) < dataSize) { printf("FAILURE %d\n", __LINE__);fflush(stdout); // Try to do it again... if (!ReOpenConnection(s)) { printf("FAILURE %d\n", __LINE__);fflush(stdout); return 0; } if (send(s->fd, data, dataSize, 0) < dataSize) { printf("FAILURE %d\n", __LINE__);fflush(stdout); unlock_fd(p); return 0; } } int nbytes; char* pOriginalBuffer = pbBuffer; int originaldwBytesToRead = max_len; int bytesRead = 0; nbytes = recv(s->fd, (char*)pbBuffer, max_len, 0); while (nbytes >= 0 && max_len > 0) { max_len -= nbytes; pbBuffer += nbytes; bytesRead += nbytes; if (max_len > 0) nbytes = recv(s->fd, (char*)pbBuffer, max_len, 0); } if (nbytes < 0) { printf("FAILURE %d\n", __LINE__);fflush(stdout); if (!ReOpenConnection(s)) { printf("FAILURE %d\n", __LINE__);fflush(stdout); return 0; } if (send(s->fd, data, dataSize, 0) < dataSize) { printf("FAILURE %d\n", __LINE__);fflush(stdout); unlock_fd(p); return 0; } bytesRead = 0; pbBuffer = pOriginalBuffer; max_len = originaldwBytesToRead; nbytes = recv(s->fd, (char*)pbBuffer, max_len, 0); while (nbytes >= 0 && max_len > 0) { max_len -= nbytes; pbBuffer += nbytes; bytesRead += nbytes; if (max_len > 0) nbytes = recv(s->fd, (char*)pbBuffer, max_len, 0); } if (nbytes < 0) { //printf("FAILURE %d\n", __LINE__);fflush(stdout); unlock_fd(p); return 0; } } unlock_fd(p); //printf("Read %d bytes from network\n", bytesRead);fflush(stdout); //s->pos += bytesRead; // for mplayer this is handled externally to us // Check in case the server's flipped the active file flag and we're not an integrated player if (s->activeFileFlag) { p->actualSize = size(s, NULL); if (s->activeFileFlag) p->actualSize = 0; else { //printf("Active file flag flipped!!!\n");fflush(stdout); // Flag got flipped, make sure we don't have overage! bytesRead = min(bytesRead, p->actualSize - s->pos); } } return bytesRead; }
static off_t size(struct stream_st *s, off_t *availSize) { struct stream_priv_s* p = (struct stream_priv_s*)s->priv; char data[512]; off_t otherAvail; if (!availSize) availSize = &otherAvail; sprintf(data, "SIZE\r\n"); int dataSize = strlen(data); if (!lock_fd(p)) return 0; //printf("Sending2 cmd to SageTV Server:%s\n", data);fflush(stdout); if (send(s->fd, data, dataSize, 0) < dataSize) { printf("FAILURE %d\n", __LINE__);fflush(stdout); // printf("socket write failed, reopening...\n"); if (!ReOpenConnection(s)) { printf("FAILURE %d\n", __LINE__);fflush(stdout); return 0; } if (send(s->fd, data, dataSize, 0) < dataSize) { printf("FAILURE %d\n", __LINE__);fflush(stdout); unlock_fd(p); return 0; } } int nbytes = sockReadLine(s->fd, data, sizeof(data)); if (nbytes < 0) { printf("FAILURE %d\n", __LINE__);fflush(stdout); if (!ReOpenConnection(s)) { printf("FAILURE %d\n", __LINE__);fflush(stdout); return 0; } sprintf(data, "SIZE\r\n"); if (send(s->fd, data, dataSize, 0) < dataSize) { printf("FAILURE %d\n", __LINE__);fflush(stdout); unlock_fd(p); return 0; } nbytes = sockReadLine(s->fd, data, sizeof(data)); if (nbytes < 0) { printf("FAILURE %d\n", __LINE__);fflush(stdout); unlock_fd(p); return 0; } } // printf("Read back %s\n", data);fflush(stdout); unlock_fd(p); char* spacePtr = strchr(data, ' '); if (!spacePtr) { printf("FAILURE %d\n", __LINE__);fflush(stdout); return 0; } *spacePtr = '\0'; if (availSize) *availSize = strtoll(data, NULL, 10); off_t totalSize = strtoll(spacePtr + 1, NULL, 10); //printf("avail=%I64d total=%I64d\n", *availSize, totalSize);fflush(stdout); if (*availSize != totalSize) { // Be sure the active file flag is set! if (!s->activeFileFlag) { if (s->cache_data) { cache_vars_t* sc = s->cache_data; sc->streamOriginal->activeFileFlag = 1; } s->activeFileFlag = 1; } active_file = 1; } else { // If we're going to turn it on we better turn it off as well! if (s->activeFileFlag) { if (s->cache_data) { cache_vars_t* sc = s->cache_data; sc->streamOriginal->activeFileFlag = 0; } s->activeFileFlag = 0; } active_file = 0; } return totalSize; }
static int seek(stream_t *s,off_t newpos) { struct stream_priv_s* p = (struct stream_priv_s*)s->priv; if (newpos >= 0 && s->activeFileFlag) { s->pos = newpos; return 1; } if (!lock_fd(p)) { printf("FAILURE %d\n", __LINE__);fflush(stdout); return 0; } char data[512]; sprintf(data, "SIZE\r\n"); int dataSize = strlen(data); //printf("Sending cmd to SageTV Server:%s", data);fflush(stdout); if (send(s->fd, data, dataSize, 0) < dataSize) { printf("FAILURE %d\n", __LINE__);fflush(stdout); if (!ReOpenConnection(s)) { printf("FAILURE %d\n", __LINE__);fflush(stdout); return 0; } if (send(s->fd, data, dataSize, 0) < dataSize) { printf("FAILURE %d\n", __LINE__);fflush(stdout); unlock_fd(p); return 0; } } int nbytes = sockReadLine(s->fd, data, sizeof(data)); if (nbytes < 0) { printf("FAILURE %d\n", __LINE__);fflush(stdout); if (!ReOpenConnection(s)) { printf("FAILURE %d\n", __LINE__);fflush(stdout); return 0; } sprintf(data, "SIZE\r\n"); if (send(s->fd, data, dataSize, 0) < dataSize) { printf("FAILURE %d\n", __LINE__);fflush(stdout); unlock_fd(p); return 0; } nbytes = sockReadLine(s->fd, data, sizeof(data)); if (nbytes < 0) { printf("FAILURE %d\n", __LINE__);fflush(stdout); unlock_fd(p); return 0; } } unlock_fd(p); char* spacePtr = strchr(data, ' '); if (!spacePtr) { printf("FAILURE %d\n", __LINE__);fflush(stdout); return 0; } *spacePtr = '\0'; off_t availSize = strtoll(data, NULL, 10); if (newpos >= 0 && (newpos < availSize || s->activeFileFlag)) { s->pos = newpos; return 1; } else { printf("FAILURE %d\n", __LINE__);fflush(stdout); return 0; } }
/* * unlock_file() --- unlock file using FILE * */ int unlock_file(FILE *fp) { return unlock_fd( fileno(fp) ); }
enum nh_restore_status nh_restore_game(int fd, struct nh_window_procs *rwinprocs, boolean force_replay) { int playmode, irole, irace, igend, ialign; char namebuf[PL_NSIZ]; /* some compilers can't cope with the fact that all subsequent stores to error * are not dead, but become important if the error handler longjumps back * volatile is required to prevent invalid optimization based on that wrong * assumption. */ volatile enum nh_restore_status error = GAME_RESTORED; if (fd == -1) return ERR_BAD_ARGS; switch (nh_get_savegame_status(fd, NULL)) { case LS_INVALID: return ERR_BAD_FILE; case LS_DONE: return ERR_GAME_OVER; case LS_CRASHED: force_replay = TRUE; break; case LS_IN_PROGRESS: return ERR_IN_PROGRESS; case LS_SAVED: break; /* default, everything is A-OK */ } if (!api_entry_checkpoint()) goto error_out; error = ERR_BAD_FILE; replay_set_logfile(fd); /* store the fd and try to get a lock or exit */ replay_begin(); program_state.restoring = TRUE; iflags.disable_log = TRUE; /* don't log any of the commands, they're already in the log */ /* Read the log header for this game. */ replay_read_newgame(&turntime, &playmode, namebuf, &irole, &irace, &igend, &ialign); /* set special windowprocs which will autofill requests for user input * with data from the log file */ replay_setup_windowprocs(rwinprocs); startup_common(namebuf, playmode); u.initrole = irole; u.initrace = irace; u.initgend = igend; u.initalign = ialign; if (!force_replay) { error = ERR_RESTORE_FAILED; replay_run_cmdloop(TRUE, FALSE, TRUE); replay_jump_to_endpos(); if (!dorecover_fd(fd)) { replay_undo_jump_to_endpos(); goto error_out2; } replay_undo_jump_to_endpos(); wd_message(); program_state.game_running = 1; post_init_tasks(); } else { replay_run_cmdloop(TRUE, TRUE, FALSE); /* option setup only */ newgame(); /* try replaying instead */ error = ERR_REPLAY_FAILED; replay_run_cmdloop(FALSE, FALSE, TRUE); replay_sync_save(); } /* restore standard window procs */ replay_restore_windowprocs(); program_state.restoring = FALSE; iflags.disable_log = FALSE; /* clean up data used for replay */ replay_end(); log_truncate(); log_init(); /* must be called before we start writing to the log */ /* info might not have reached the ui while alternate window procs were set */ doredraw(); /* nh_start_game() does this via newgame(), but since this function doesn't * call newgame(), we have to do it here instead. */ notify_levelchange(NULL); bot(); flush_screen(); was_on_elbereth = !sengr_at("Elbereth", u.ux, u.uy); /* force botl update later */ welcome(FALSE); realtime_messages(TRUE, TRUE); update_inventory(); api_exit(); return GAME_RESTORED; error_out2: api_exit(); error_out: replay_restore_windowprocs(); program_state.restoring = FALSE; iflags.disable_log = FALSE; replay_end(); unlock_fd(fd); if (error == ERR_RESTORE_FAILED) { raw_printf("Restore failed. Attempting to replay instead.\n"); error = nh_restore_game(fd, rwinprocs, TRUE); } return error; }