diff options
Diffstat (limited to 'mcast/tool/.svn/text-base/netcvupdate.c.svn-base')
-rw-r--r-- | mcast/tool/.svn/text-base/netcvupdate.c.svn-base | 773 |
1 files changed, 773 insertions, 0 deletions
diff --git a/mcast/tool/.svn/text-base/netcvupdate.c.svn-base b/mcast/tool/.svn/text-base/netcvupdate.c.svn-base new file mode 100644 index 0000000..e311470 --- /dev/null +++ b/mcast/tool/.svn/text-base/netcvupdate.c.svn-base @@ -0,0 +1,773 @@ +/*------------------------------------------------------------------------ + * netcvupdate - NetCeiver update tool + * + * Principle for firmware update + * - Unpack given .tgz into host /tmp/mkdtemp() + * - "md5sum -c md5sums.txt" + * - read script file update.scr + * - feed commands into tnftp + * + * + *------------------------------------------------------------------------*/ +#define USE_MCLI_API + +#ifdef USE_MCLI_API +#include "headers.h" +#else +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <errno.h> +#include <unistd.h> +#include <signal.h> +#include <ctype.h> +#endif + +#define STATE_FILE "update.log" +#define FTP_CMD "ftp" +#define NC_CONFPATH "/mmc/etc/" +#define NC_CONFFILE "netceiver.conf" + +char ftp_cmd[512]=FTP_CMD; +int verbose=0; +int no_reboot=0; +char username[256]="root"; +char password[256]="root"; +char device[256]="eth0"; +char *uuids[256]={0}; +char *versions[256]={0}; +int num_uuids=0; +char socket_path[256]=API_SOCK_NAMESPACE; + +#ifdef USE_MCLI_API +/*------------------------------------------------------------------------*/ +#define API_WAIT_RESPONSE(cmd) { cmd->state=API_REQUEST; \ + send (sock_comm, &sock_cmd, sizeof(api_cmd_t), 0); \ + recv (sock_comm, &sock_cmd, sizeof(api_cmd_t), 0); \ + if (cmd->state == API_ERROR) {warn ( "SHM parameter error, incompatible versions?\n"); exit(-1);}} + +int sock_comm; + +int api_init(char *path) +{ + int sock_name_len = 0; + struct sockaddr_un sock_name; + sock_name.sun_family = AF_UNIX; + + strcpy(sock_name.sun_path, path); + sock_name_len = sizeof(struct sockaddr_un); + + if((sock_comm = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) + { + warn ("socket create failure %d\n", errno); + return -1; + } + + if (connect(sock_comm, (struct sockaddr*)&sock_name, sock_name_len) < 0) { + warn ("connect failure to %s: %s (are you root?)\n",path, strerror(errno)); + return -1; + } + return 0; +} +#endif +/*------------------------------------------------------------------------*/ +void add_upload(char* cmd, char* localfile, char *remotepath, char *remotefile) +{ + char tmp[1024]; + sprintf(tmp, + "cd %s\n" + "site exec rm -f /tmp/update/%s\n" + "put %s\n", + remotepath, remotefile, localfile); + strcat(cmd,tmp); +} +/*------------------------------------------------------------------------*/ +void add_download(char* cmd, char *remotepath, char *remotefile) +{ + char tmp[1024]; + sprintf(tmp, + "cd %s\n" + "get %s\n", + remotepath,remotefile); + strcat(cmd,tmp); +} +/*------------------------------------------------------------------------*/ +int script_interpreter(char *script, char *line, + char *ip, char *iface, char *user, char *pwd) +{ + char cmd[256],p1[256],p2[256]; + int end=0; + + *cmd=0; + *p1=0; + *p2=0; + sscanf(line,"%s %s %s\n",cmd,p1,p2); + + if (cmd[0]=='#') + return 0; + if (!strcmp(cmd,"connect")) { + char tmp[1024]; + sprintf(tmp, + "open %s%%%s\n" + "user %s %s\n", + ip,iface,user,pwd); + strcat(script,tmp); + } + else if (!strcmp(cmd,"upload")) { + add_upload(script,p2,p1,p2); + } + else if (!strcmp(cmd,"download")) { + add_download(script,p1,p2); + } + else if (!strcmp(cmd,"exit")) { + strcat(script,"quit\n"); + end=1; + } + else { + strcat(script,line); + } + return end; +} +/*------------------------------------------------------------------------*/ +char script[128*1024]; +int generate_script(char *filename, char *tmpname, char *ip, char *iface, char *user, char *pwd) +{ + FILE *f; + f=fopen(filename,"r"); + if (!f) { + fprintf(stderr,"Can't open script file <%s>: %s\n",filename,strerror(errno)); + return -1; + } + script[0]=0; + + while(!feof(f)) { + char line[256]; + fgets(line,255,f); + if (script_interpreter(script,line,ip,iface,user,pwd)) + break; + } + fclose(f); + return 0; +} +/*------------------------------------------------------------------------*/ +int check_state_file(char *tmpname) +{ + char cmd[512]; + int ret; + printf("\nUPDATE RESULT:\n"); + snprintf(cmd,512,"cat %s/update.log",tmpname); + ret=system(cmd); + printf("\n"); + return ret; +} +/*------------------------------------------------------------------------*/ +void sigground(int x) +{ +} +/*------------------------------------------------------------------------*/ +int run_ftp(char *tmpdir,char *script, int timeout, char *pipeout) +{ + FILE *f; + char cmd[512]; + int ret; + if (!strlen(ftp_cmd)) + return -1; + signal(SIGPIPE,sigground); + if (strlen(tmpdir)) +// snprintf(cmd,511,"cd %s; %s -q %i -n %s",tmpdir,ftp_cmd,timeout,verbose?"":"-V"); + snprintf(cmd,511,"cd %s; %s -n %s %s",tmpdir,ftp_cmd,verbose?"":"-V",pipeout); + else + snprintf(cmd,511,"%s -q %i -n %s %s",ftp_cmd,timeout,verbose?"":"-V",pipeout); + + f=popen(cmd,"w"); + if (!f) + return -1; + fputs(script,f); + ret=pclose(f); + return ret; +} +/*------------------------------------------------------------------------*/ +int do_reboot(char *tmpdir, char *ip, char* iface, char *user, char* pwd) +{ + sprintf(script, + "open %s%%%s\n" + "user %s %s\n" + "site exec reboot -d 5\n" + "quit\n" + , + ip,iface,user,pwd); + return run_ftp(tmpdir, script, 15,""); +} +/*------------------------------------------------------------------------*/ + +int do_list_fw(char *tmpdir, char *ip, char* iface, char *user, char* pwd, int maxf, int *found, char **versions) +{ + char tmpfile[256]="/tmp/ncvup.XXXXXX"; + char pipeout[256]; + int n=0; + int ret=0; + FILE *file; + + *found=0; + + if (!mkstemp(tmpfile)) { + fprintf(stderr,"Can't make temporary directory %s!\n",tmpfile); + return -2; + } + + sprintf(script, + "open %s%%%s\n" + "user %s %s\n" + "ls /mmc/\n" + "quit\n" + , + ip,iface,user,pwd); + sprintf(pipeout," > %s",tmpfile); + ret=run_ftp(tmpdir, script, 15, pipeout); + if (ret) { + unlink(tmpfile); + return ret; + } + + file=fopen(tmpfile,"r"); + if (!file) { + unlink(tmpfile); // ? + perror("Can't read temp file"); + return ret; + } + + while(!feof(file)) { + char line[1024]; + char *p; + *line=0; + fgets(line, 1023,file); + line[1023]=0; + p=strstr(line,"etceivr."); + if (p) { + + char *pp=strchr(p,'\n'); + if (pp) + *pp=0; + + if (n < maxf) { + n++; + *versions++=strdup(p-1); + } + } + } + *found=n; + fclose(file); + unlink(tmpfile); + return 0; +} +/*------------------------------------------------------------------------*/ +int do_kill(char *tmpdir, char *ip, char* iface, char *user, char* pwd) +{ + sprintf(script, + "open %s%%%s\n" + "user %s %s\n" + "site exec killall -9 mserv\n" + "quit\n" + , + ip,iface,user,pwd); + return run_ftp(tmpdir, script, 15,""); +} +/*------------------------------------------------------------------------*/ +int do_single_update(char *tmpdir, char *uuid, char *device) +{ + char path[256]; + int ret; + + snprintf(path,255,"%s/%s",tmpdir,"update.scr"); + if (generate_script(path, tmpdir, uuid, device, username, password)) + return -1; +// puts(script); + + printf("Upload update... "); + fflush(stdout); + + ret=run_ftp(tmpdir, script, 600,""); + if (ret) + return ret; + + printf("check result... \n"); + fflush(stdout); + + if (check_state_file(tmpdir)) + return -1; + +#if 1 + if (!no_reboot) { + printf("Issue Reboot... "); + fflush(stdout); + ret=do_reboot(tmpdir, uuid, device, username, password); + if (!ret) + return ret; + } +#endif + return 0; +} +/*------------------------------------------------------------------------*/ +int do_single_upload( char *uuid, char *device, char *remote_path, char *fname, char *remote_file) +{ + int ret; + sprintf(script, + "open %s%%%s\n" + "user %s %s\n" + "cd %s\n" + "put %s %s\n" +// "site exec killall -HUP mserv\n" + "quit", + uuid,device,username,password,remote_path,fname,remote_file); + ret=run_ftp("", script, 120,""); + return ret; +} +/*------------------------------------------------------------------------*/ +int do_single_download( char *uuid, char *device, char *remote_path, char *fname) +{ + int ret; + sprintf(script, + "open %s%%%s\n" + "user %s %s\n" + "cd %s\n" + "get %s\n" + "quit", + uuid,device,username,password,remote_path,fname); + ret=run_ftp("", script, 120,""); + return ret; +} +/*------------------------------------------------------------------------*/ +int fw_action(char *uuid, char* iface, char *user, char* pwd, int mode, char *version) +{ + int ret; + if (mode==0) { // inactivate + printf("Inactivating version %s\n",version); + sprintf(script, + "open %s%%%s\n" + "user %s %s\n" + "cd /mmc\n" + "rename netceivr.%s xetceivr.%s\n" + "quit", + uuid,device,username,password,version,version); + ret=run_ftp("", script, 120,""); + return ret; + } + else if (mode==1) { // enable + printf("Enabling version %s\n",version); + sprintf(script, + "open %s%%%s\n" + "user %s %s\n" + "cd /mmc\n" + "rename xetceivr.%s netceivr.%s\n" + "quit", + uuid,device,username,password,version,version); + ret=run_ftp("", script, 120,""); + return ret; + } + else if (mode==2) { // delete + printf("Removing version %s\n",version); + sprintf(script, + "open %s%%%s\n" + "user %s %s\n" + "site exec rm -rf /mmc/netceivr.%s\n" + "site exec rm -rf /mmc/xetceivr.%s\n" + "quit", + uuid,device,username,password,version,version); + ret=run_ftp("", script, 120,""); + return ret; + } + return 0; +} +/*------------------------------------------------------------------------*/ +int cleanup(char *tmpdir) +{ + int ret; + char cmd[1024]; + snprintf(cmd,1024,"rm -rf '%s'",tmpdir); +// puts(cmd); + ret=system(cmd); + return ret; +} +/*------------------------------------------------------------------------*/ +int unpack(char *tmpdir, char *file) +{ + int ret; + char cmd[1024]; + snprintf(cmd,1024,"tar xfz '%s' --directory %s",file,tmpdir); +// puts(cmd); + ret=system(cmd); + return ret; +} +/*------------------------------------------------------------------------*/ +int check_xml(char *file) +{ + int ret; + char cmd[1024]; + snprintf(cmd,1024,"xmllint --noout '%s'\n",file); +// puts(cmd); + ret=system(cmd); + return ret; +} +/*------------------------------------------------------------------------*/ +int check_integrity(char *tmpdir) +{ + int ret; + char cmd[1024]; + snprintf(cmd,1024,"cd %s; md5sum -c --status md5sums.txt \n",tmpdir); +// puts(cmd); + ret=system(cmd); + return ret; +} +/*------------------------------------------------------------------------*/ +int do_update(char **uuids, int num_uuids, char *device, char *optarg) +{ + char tmpdir[256]="/tmp/ncvupXXXXXX"; + int n; + int ret=0; + if (!mkdtemp(tmpdir)) { + fprintf(stderr,"Can't make temporary directory %s!\n",tmpdir); + return -2; + } +// printf("TEMP DIR %s\n",tmpdir); + if (unpack(tmpdir,optarg)) { + fprintf(stderr,"Update file <%s> cannot be unpacked!\n",optarg); + cleanup(tmpdir); + return -2; + } + if (check_integrity(tmpdir)) { + fprintf(stderr,"Update file <%s> corrupted!\n",optarg); + cleanup(tmpdir); + return -2; + } + printf("Update file integrity OK\n"); + printf("NUM uuids %i\n",num_uuids); + for(n=0;n<num_uuids;n++) { + if (!uuids[n]) + continue; + + printf("UUID %s: ",uuids[n]); + fflush(stdout); + ret=do_single_update(tmpdir, uuids[n], device); + if (!ret) + printf("-> Update done <-\n"); + else { + printf("-> Update failed (ret=%i) <-\n",ret); + uuids[n]=NULL; + } + } + + cleanup(tmpdir); + return ret; +} +/*------------------------------------------------------------------------*/ +int do_upload(char **uuids, int num_uuids, char *device, char *optarg) +{ + int n; + int ret=0; + if (check_xml(optarg)) { + fprintf(stderr,"Configuration file <%s> not valid XML\n",optarg); + return -2; + } + for(n=0;n<num_uuids;n++) { + if (!uuids[n]) + continue; + + printf("UUID %s: Uploading %s ... ",uuids[n], optarg); + fflush(stdout); + ret=do_single_upload(uuids[n], device, "/mmc/etc/", optarg, NC_CONFFILE); + if (!ret) + printf("Upload done\n"); + else { + printf("Upload failed (ret=%i)\n",ret); + uuids[n]=NULL; + } + } + return ret; +} +/*------------------------------------------------------------------------*/ +int do_download(char **uuids, int num_uuids, char *device, char *remotepath, char *file) +{ + int n,ret=0; + + for(n=0;n<num_uuids;n++) { + char newfile[1024]; + if (!uuids[n]) + continue; + + if (num_uuids!=1) + snprintf(newfile,1024,"%s-%s",file,uuids[n]); + else + strncpy(newfile,file,1024); + + printf("UUID %s: Downloading %s ... ",uuids[n], newfile); + fflush(stdout); + ret=do_single_download(uuids[n], device, remotepath, file); + if (!ret) { + printf("Done\n"); + if (num_uuids!=1) + rename(file,newfile); + } + else { + printf("Download failed (ret=%i)\n",ret); + uuids[n]=NULL; + } + } + return ret; +} +/*------------------------------------------------------------------------*/ +int do_all_reboot(char **uuids, int num_uuids, char *device) +{ + int n,ret=0; + + for(n=0;n<num_uuids;n++) { + if (!uuids[n]) + continue; + printf("UUID %s: Issue Reboot... ",uuids[n]); + fflush(stdout); + ret=do_reboot("/tmp", uuids[n], device, username, password); + if (!ret) + printf("Reboot done\n"); + else + printf("Reboot failed (ret=%i)\n",ret); + } + return ret; +} +/*------------------------------------------------------------------------*/ +int do_all_kill(char **uuids, int num_uuids, char *device) +{ + int n,ret=0; + + for(n=0;n<num_uuids;n++) { + if (!uuids[n]) + continue; + printf("UUID %s: Issue Kill... ",uuids[n]); + fflush(stdout); + ret=do_kill("/tmp", uuids[n], device, username, password); + if (!ret) + printf("Kill done\n"); + else + printf("Kill failed (ret=%i)\n",ret); + } + return ret; +} +/*------------------------------------------------------------------------*/ +int get_uuids(char **uuids, int max) +{ + int count,n; + api_cmd_t sock_cmd; + api_cmd_t *api_cmd=&sock_cmd; + + if (api_init(socket_path)==-1) { + exit(-1); + } + api_cmd->cmd=API_GET_NC_NUM; + api_cmd->magic = MCLI_MAGIC; + api_cmd->version = MCLI_VERSION; + API_WAIT_RESPONSE(api_cmd); + if(api_cmd->magic != MCLI_MAGIC || api_cmd->version != MCLI_VERSION) { + err("API version mismatch!\n"); + } + count=api_cmd->parm[API_PARM_NC_NUM]; + + for(n=0;n<max && n<count;n++) { + api_cmd->cmd=API_GET_NC_INFO; + api_cmd->parm[API_PARM_NC_NUM]=n; + API_WAIT_RESPONSE(api_cmd); + if(api_cmd->u.nc_info.magic != MCLI_MAGIC || api_cmd->u.nc_info.version != MCLI_VERSION) { + err("API version mismatch!\n"); + } + + uuids[n]=strdup(api_cmd->u.nc_info.uuid); + versions[n]=strdup(api_cmd->u.nc_info.FirmwareVersion); + } + return count; +} +/*------------------------------------------------------------------------*/ +int show_uuids(void) +{ + char *uuids[256]={0}; + int num_uuids,n; + num_uuids=get_uuids(uuids,256); + for(n=0;n<num_uuids;n++) { + printf("%s %s\n",uuids[n],versions[n]); + } + return 0; +} +/*------------------------------------------------------------------------*/ +#define MAX_FWS 64 +void show_firmwares(char *uuid, char *device, char *username, char *passwd) +{ + char *fwversions[MAX_FWS]; + int found,m; + found=0; + + do_list_fw("/tmp", uuid, device, username, password, MAX_FWS, &found, fwversions); + + printf("Firmware versions found: %i\n Versions: ", found); + for(m=0;m<found;m++) { + if (m!=0) printf(", "); + if (fwversions[m][0]!='n') + printf("%s (disabled)",fwversions[m]+9); + else + printf("%s",fwversions[m]+9); + + free(versions[m]); + } + puts(""); +} +/*------------------------------------------------------------------------*/ + +int show_all_firmwares(char **uuids, int num_uuids) +{ + int n; + + for(n=0;n<num_uuids;n++) { + printf("%s: ",uuids[n]); + fflush(stdout); + show_firmwares(uuids[n],device,username,password); + } + return 0; +} +/*------------------------------------------------------------------------*/ +void do_fw_actions(char **uuids, int max, int mode, char *version) +{ + int n; + + if (strlen(version)!=3 || !strcmp(version,"000")) { + fprintf(stderr,"Invalid version number\n"); + return; + } + + for(n=0;n<3;n++) + version[n]=toupper(version[n]); + + for(n=0;n<max;n++) { + printf("UUID %s\n",uuids[n]); + if (fw_action(uuids[n], device, username, password, mode, version)) { + fprintf(stderr,"Failed\n"); + return; + } + show_firmwares(uuids[n],device,username,password); + } +} +/*------------------------------------------------------------------------*/ +void usage(void) +{ + fprintf(stderr, + "netcvupdate - NetCeiver update tool, version " MCLI_VERSION_STR "\n" + "(c) BayCom GmbH\n" + "Usage: netcvupdate <options> <actions> \n" + "Actions: \n" + " -l List all seen NetCeivers and their UUID\n" + " -L List available FWs\n" + " -X <Update.tgz> Update with given file\n" + " -U <configfile> Upload configfile\n" + " -D Download configfile netceiver.conf\n" + " -I <version> Inactivate FW version\n" + " -E <version> Enable FW version\n" + " -Z <version> Remove FW version\n" + " -K Restart streaming server\n" + " -R Issue reboot\n" + "Options:\n" + " -A Use all found NetCeivers (mcli must be running)\n" + " -i <uuid> Use specific UUID (can be used multiple times)\n" + " *** Either -A or -i must be given for most actions! ***\n" + "Rare options:\n" + " -d <device> Set network device (default: eth0)\n" + " -F <ftp-command> Set ftp command/path\n" + " *** ftp command must understand the -q (timeout) option! ***\n" + " -P <path> Set API socket\n" + " -u <user> Set username\n" + " -p <password> Set password\n" + " -r No reboot after update\n" + " -q Be more quiet\n" + ); + exit(0); +} +/*------------------------------------------------------------------------*/ +int main(int argc, char **argv) +{ + int ret=0; + + while(1) { + int ret = getopt(argc,argv, "U:X:Di:AlLI:E:Z:d:F:P:u:p:rRqK"); + if (ret==-1) + break; + + char c=(char)ret; + + switch(c) { + case 'F': + strncpy(ftp_cmd,optarg,512); + ftp_cmd[511]=0; + break; + case 'X': + ret=do_update(uuids, num_uuids, device, optarg); + if (ret==-2) + exit(ret); + break; + case 'U': + ret=do_upload(uuids, num_uuids, device, optarg); + if (ret==-2) + exit(ret); + break; + case 'D': + ret|=do_download(uuids, num_uuids, device, NC_CONFPATH, NC_CONFFILE); + break; + case 'i': + uuids[num_uuids]=strdup(optarg); + num_uuids++; + break; + case 'A': + num_uuids=get_uuids(uuids,255); + break; + case 'l': + show_uuids(); + break; + case 'd': + strncpy(device,optarg,255); + device[255]=0; + break; + case 'P': + strncpy(socket_path,optarg,255); + socket_path[255]=0; + break; + case 'p': + strncpy(password,optarg,255); + password[255]=0; + break; + case 'u': + strncpy(username,optarg,255); + username[255]=0; + break; + case 'r': + no_reboot=1; + break; + case 'K': + ret|=do_all_kill(uuids,num_uuids,device); + break; + case 'R': + ret|=do_all_reboot(uuids, num_uuids, device); + break; + case 'L': + show_all_firmwares(uuids, num_uuids); + break; + case 'I': + do_fw_actions(uuids, num_uuids, 0, optarg); + break; + case 'E': + do_fw_actions(uuids, num_uuids, 1, optarg); + break; + case 'Z': + do_fw_actions(uuids, num_uuids, 2, optarg); + break; + case 'q': + verbose=0; + break; + default: + usage(); + break; + } + } + exit(ret); +} |