@@ -9788,11 +9788,96 @@ bool starts_with(const char *str, const char *prefix)
9788
9788
return strncmp (prefix , str , strlen (prefix )) == 0 ;
9789
9789
}
9790
9790
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
+
9791
9874
void parse_add_command_pmt (char * add_command )
9792
9875
{
9793
9876
char * name = NULL ;
9794
9877
char * type_name = NULL ;
9795
9878
char * format_name = NULL ;
9879
+ char * direct_path = NULL ;
9880
+ static const char direct_path_prefix [] = "path=" ;
9796
9881
unsigned int offset ;
9797
9882
unsigned int lsb ;
9798
9883
unsigned int msb ;
@@ -9881,6 +9966,10 @@ void parse_add_command_pmt(char *add_command)
9881
9966
goto next ;
9882
9967
}
9883
9968
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
+ }
9884
9973
next :
9885
9974
add_command = strchr (add_command , ',' );
9886
9975
if (add_command ) {
@@ -9952,8 +10041,24 @@ void parse_add_command_pmt(char *add_command)
9952
10041
exit (1 );
9953
10042
}
9954
10043
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
+
9955
10060
if (!has_guid ) {
9956
- printf ("%s: missing %s\n" , __func__ , "guid" );
10061
+ printf ("%s: missing %s\n" , __func__ , "guid or path " );
9957
10062
exit (1 );
9958
10063
}
9959
10064
0 commit comments