@@ -9788,11 +9788,96 @@ bool starts_with(const char *str, const char *prefix)
97889788 return strncmp (prefix , str , strlen (prefix )) == 0 ;
97899789}
97909790
9791+ int pmt_parse_from_path (const char * target_path , unsigned int * out_guid , unsigned int * out_seq )
9792+ {
9793+ struct pmt_diriter_t pmt_iter ;
9794+ const struct dirent * dirname ;
9795+ struct stat stat , target_stat ;
9796+ int fd_telem_dir = -1 ;
9797+ int fd_target_dir ;
9798+ unsigned int seq = 0 ;
9799+ unsigned long guid , target_guid ;
9800+ int ret = -1 ;
9801+
9802+ fd_target_dir = open (target_path , O_RDONLY | O_DIRECTORY );
9803+ if (fd_target_dir == -1 ) {
9804+ return -1 ;
9805+ }
9806+
9807+ if (fstat (fd_target_dir , & target_stat ) == -1 ) {
9808+ fprintf (stderr , "%s: Failed to stat the target: %s" , __func__ , strerror (errno ));
9809+ exit (1 );
9810+ }
9811+
9812+ if (parse_telem_info_file (fd_target_dir , "guid" , "%lx" , & target_guid )) {
9813+ fprintf (stderr , "%s: Failed to parse the target guid file: %s" , __func__ , strerror (errno ));
9814+ exit (1 );
9815+ }
9816+
9817+ close (fd_target_dir );
9818+
9819+ pmt_diriter_init (& pmt_iter );
9820+
9821+ for (dirname = pmt_diriter_begin (& pmt_iter , SYSFS_TELEM_PATH ); dirname != NULL ;
9822+ dirname = pmt_diriter_next (& pmt_iter )) {
9823+
9824+ fd_telem_dir = openat (dirfd (pmt_iter .dir ), dirname -> d_name , O_RDONLY | O_DIRECTORY );
9825+ if (fd_telem_dir == -1 ) {
9826+ continue ;
9827+ }
9828+
9829+ if (parse_telem_info_file (fd_telem_dir , "guid" , "%lx" , & guid )) {
9830+ fprintf (stderr , "%s: Failed to parse the guid file: %s" , __func__ , strerror (errno ));
9831+ continue ;
9832+ }
9833+
9834+ if (fstat (fd_telem_dir , & stat ) == -1 ) {
9835+ fprintf (stderr , "%s: Failed to stat %s directory: %s" , __func__ ,
9836+ dirname -> d_name , strerror (errno ));
9837+ continue ;
9838+ }
9839+
9840+ /*
9841+ * If reached the same directory as target, exit the loop.
9842+ * Seq has the correct value now.
9843+ */
9844+ if (stat .st_dev == target_stat .st_dev && stat .st_ino == target_stat .st_ino ) {
9845+ ret = 0 ;
9846+ break ;
9847+ }
9848+
9849+ /*
9850+ * If reached directory with the same guid,
9851+ * but it's not the target directory yet,
9852+ * increment seq and continue the search.
9853+ */
9854+ if (guid == target_guid )
9855+ ++ seq ;
9856+
9857+ close (fd_telem_dir );
9858+ fd_telem_dir = -1 ;
9859+ }
9860+
9861+ pmt_diriter_remove (& pmt_iter );
9862+
9863+ if (fd_telem_dir != -1 )
9864+ close (fd_telem_dir );
9865+
9866+ if (!ret ) {
9867+ * out_guid = target_guid ;
9868+ * out_seq = seq ;
9869+ }
9870+
9871+ return ret ;
9872+ }
9873+
97919874void parse_add_command_pmt (char * add_command )
97929875{
97939876 char * name = NULL ;
97949877 char * type_name = NULL ;
97959878 char * format_name = NULL ;
9879+ char * direct_path = NULL ;
9880+ static const char direct_path_prefix [] = "path=" ;
97969881 unsigned int offset ;
97979882 unsigned int lsb ;
97989883 unsigned int msb ;
@@ -9881,6 +9966,10 @@ void parse_add_command_pmt(char *add_command)
98819966 goto next ;
98829967 }
98839968
9969+ if (strncmp (add_command , direct_path_prefix , strlen (direct_path_prefix )) == 0 ) {
9970+ direct_path = add_command + strlen (direct_path_prefix );
9971+ goto next ;
9972+ }
98849973next :
98859974 add_command = strchr (add_command , ',' );
98869975 if (add_command ) {
@@ -9952,8 +10041,24 @@ void parse_add_command_pmt(char *add_command)
995210041 exit (1 );
995310042 }
995410043
10044+ if (direct_path && has_guid ) {
10045+ printf ("%s: path and guid+seq parameters are mutually exclusive\n"
10046+ "notice: passed guid=0x%x and path=%s\n" , __func__ , guid , direct_path );
10047+ exit (1 );
10048+ }
10049+
10050+ if (direct_path ) {
10051+ if (pmt_parse_from_path (direct_path , & guid , & seq )) {
10052+ printf ("%s: failed to parse PMT file from %s\n" , __func__ , direct_path );
10053+ exit (1 );
10054+ }
10055+
10056+ /* GUID was just infered from the direct path. */
10057+ has_guid = true;
10058+ }
10059+
995510060 if (!has_guid ) {
9956- printf ("%s: missing %s\n" , __func__ , "guid" );
10061+ printf ("%s: missing %s\n" , __func__ , "guid or path " );
995710062 exit (1 );
995810063 }
995910064
0 commit comments