// build: // cc -Wall $(pkg-config --cflags --libs libssh plplot) -lm -o remote_plot_old_no_gtk remote_plot_old_no_gtk.c // references: // https://api.libssh.org/stable/libssh_tutorial.html // https://api.libssh.org/stable/libssh_tutor_guided_tour.html // plplot example 17 #include #include #include #include // verify_knownhost() #include #include #include // open() // plplot #include #include #include //#include #include #include // very small also works, just transfter delays, I test accelerometer data is // like 15782 which is 7 bytes consider newline and \0? #define MAX_XFER_BUF_SIZE 7 // Variables for holding error return info from PLplot static PLINT pl_errcode; static char errmsg[160]; int sftp_read_sync(ssh_session session, sftp_session sftp) { int access_type; sftp_file file; char buffer[MAX_XFER_BUF_SIZE]; int nbytes, rc; access_type = O_RDONLY; PLINT id1, autoy, acc; PLFLT ymin, ymax, xlab, ylab; PLFLT t, tmin, tmax, tjump; PLINT colbox, collab, colline[4], styline[4]; PLCHAR_VECTOR legline[4]; // If db is used the plot is much more smooth. However, because of the // async X behaviour, one does not have a real-time scripcharter. // This is now disabled since it does not significantly improve the // performance on new machines and makes it difficult to use this // example non-interactively since it requires an extra pleop call after // each call to plstripa. // //plsetopt("db", ""); //plsetopt("np", ""); // User sets up plot completely except for window and data // Eventually settings in place when strip chart is created will be // remembered so that multiple strip charts can be used simultaneously. // // Specify some reasonable defaults for ymin and ymax // The plot will grow automatically if needed (but not shrink) ymin = -0.1; ymax = 0.1; // Specify initial tmin and tmax -- this determines length of window. // Also specify maximum jump in t // This can accomodate adaptive timesteps tmin = 0.; tmax = 10.; tjump = 0.3; // percentage of plot to jump // Axes options same as plbox. // Only automatic tick generation and label placement allowed // Eventually I'll make this fancier colbox = 1; collab = 3; styline[0] = colline[0] = 2; // pens color and line style styline[1] = colline[1] = 3; styline[2] = colline[2] = 4; styline[3] = colline[3] = 5; legline[0] = "in_accel_z_raw"; // pens legend legline[1] = "not_used"; legline[2] = "not_used"; legline[3] = "not_used"; xlab = 0.; ylab = 0.25; // legend position autoy = 1; // autoscale y acc = 1; // don't scrip, accumulate // Initialize plplot plinit(); pladv( 0 ); plvsta(); // Register our error variables with PLplot // From here on, we're handling all errors here plsError( &pl_errcode, errmsg ); plstripc( &id1, "bcnst", "bcnstv", tmin, tmax, tjump, ymin, ymax, xlab, ylab, autoy, acc, colbox, collab, colline, styline, legline, "t", "", "Strip chart demo" ); if ( pl_errcode ) { fprintf( stderr, "%s\n", errmsg ); exit( 1 ); } // Let plplot handle errors from here on plsError( NULL, NULL ); autoy = 0; // autoscale y acc = 1; // accumulate // This is to represent a loop over time // Let's try a random walk process for (t=0;;t++) { file = sftp_open(sftp, "/sys/bus/iio/devices/iio:device2/in_accel_z_raw", access_type, 0); if (file == NULL) { fprintf(stderr, "Can't open file for reading: %s\n", ssh_get_error(session)); return SSH_ERROR; } for (;;) { nbytes = sftp_read(file, buffer, sizeof(buffer)); if (nbytes == 0) { break; // EOF } else if (nbytes < 0) { fprintf(stderr, "Error while reading file: %s\n", ssh_get_error(session)); sftp_close(file); return SSH_ERROR; } //printf("%s",buffer); //printf("%d\n",atoi(buffer)); plstripa( id1, 0, t, atof(buffer)); } } rc = sftp_close(file); if (rc != SSH_OK) { fprintf(stderr, "Can't close the read file: %s\n", ssh_get_error(session)); return rc; } plstripd( id1 ); plend(); return SSH_OK; } // https://api.libssh.org/stable/libssh_tutor_guided_tour.html int verify_knownhost(ssh_session session) { enum ssh_known_hosts_e state; unsigned char *hash = NULL; ssh_key srv_pubkey = NULL; size_t hlen; char buf[10]; char *hexa; char *p; int cmp; int rc; rc = ssh_get_server_publickey(session, &srv_pubkey); if (rc < 0) { return -1; } rc = ssh_get_publickey_hash(srv_pubkey, SSH_PUBLICKEY_HASH_SHA1, &hash, &hlen); ssh_key_free(srv_pubkey); if (rc < 0) { return -1; } state = ssh_session_is_known_server(session); switch (state) { case SSH_KNOWN_HOSTS_OK: /* OK */ break; case SSH_KNOWN_HOSTS_CHANGED: fprintf(stderr, "Host key for server changed: it is now:\n"); ssh_print_hexa("Public key hash", hash, hlen); fprintf(stderr, "For security reasons, connection will be stopped\n"); ssh_clean_pubkey_hash(&hash); return -1; case SSH_KNOWN_HOSTS_OTHER: fprintf(stderr, "The host key for this server was not found but an other" "type of key exists.\n"); fprintf(stderr, "An attacker might change the default server key to" "confuse your client into thinking the key does not exist\n"); ssh_clean_pubkey_hash(&hash); return -1; case SSH_KNOWN_HOSTS_NOT_FOUND: fprintf(stderr, "Could not find known host file.\n"); fprintf(stderr, "If you accept the host key here, the file will be" "automatically created.\n"); /* FALL THROUGH to SSH_SERVER_NOT_KNOWN behavior */ case SSH_KNOWN_HOSTS_UNKNOWN: hexa = ssh_get_hexa(hash, hlen); fprintf(stderr,"The server is unknown. Do you trust the host key?\n"); fprintf(stderr, "Public key hash: %s\n", hexa); ssh_string_free_char(hexa); ssh_clean_pubkey_hash(&hash); p = fgets(buf, sizeof(buf), stdin); if (p == NULL) { return -1; } cmp = strncasecmp(buf, "yes", 3); if (cmp != 0) { return -1; } rc = ssh_session_update_known_hosts(session); if (rc < 0) { fprintf(stderr, "Error %s\n", strerror(errno)); return -1; } break; case SSH_KNOWN_HOSTS_ERROR: fprintf(stderr, "Error %s", ssh_get_error(session)); ssh_clean_pubkey_hash(&hash); return -1; } ssh_clean_pubkey_hash(&hash); return 0; } int main(void) { ssh_session my_ssh_session; sftp_session sftp; int rc; // Open session and set options my_ssh_session = ssh_new(); if (my_ssh_session == NULL) exit(-1); ssh_options_set(my_ssh_session, SSH_OPTIONS_HOST, "10.0.0.7"); // Connect to server rc = ssh_connect(my_ssh_session); if (rc != SSH_OK) { fprintf(stderr, "Error connecting to 10.0.0.7: %s\n", ssh_get_error(my_ssh_session)); ssh_free(my_ssh_session); exit(-1); } // Verify the server's identity // For the source code of verify_knownhost(), check previous example if (verify_knownhost(my_ssh_session) < 0) { ssh_disconnect(my_ssh_session); ssh_free(my_ssh_session); exit(-1); } // Authenticate ourselves // https://api.libssh.org/stable/libssh_tutor_authentication.html rc = ssh_userauth_publickey_auto(my_ssh_session, NULL, NULL); if (rc != SSH_AUTH_SUCCESS) { fprintf(stderr, "Error authenticating with key: %s\n", ssh_get_error(my_ssh_session)); ssh_disconnect(my_ssh_session); ssh_free(my_ssh_session); exit(-1); } sftp = sftp_new(my_ssh_session); if (sftp == NULL) { fprintf(stderr, "Error allocating SFTP session: %s\n", ssh_get_error(my_ssh_session)); return SSH_ERROR; } rc = sftp_init(sftp); if (rc != SSH_OK) { fprintf(stderr, "Error initializing SFTP session: code %d.\n", sftp_get_error(sftp)); sftp_free(sftp); return rc; } sftp_read_sync(my_ssh_session,sftp); ssh_disconnect(my_ssh_session); ssh_free(my_ssh_session); // Segmentation fault (core dumped) error, why? maybe double free? so no free is ok? //sftp_free(sftp); return 0; }