2 #include <stdio.h> /* for FILE etc */
3 #include <stdlib.h> /* for malloc */
4 #define __USE_GNU /* for strcasestr */
5 #include <string.h> /* for making ftw.h happy */
6 #include <unistd.h> /* for fork exec */
8 #include <utmp.h> /* for expand-tilde below; see commentary for this about-turn */
9 #include <sys/types.h> /* ditto */
10 #include <pwd.h> /* ditto */
13 #include "pnd_container.h"
14 #include "pnd_utility.h"
15 #include "pnd_pndfiles.h"
16 #include "pnd_discovery.h"
18 unsigned char pnd_check_login ( char *r_username, unsigned int maxlen ) {
23 f = fopen ( "/var/run/utmp", "r" );
27 while ( fread ( &b, sizeof(struct utmp), 1, f ) == 1 ) {
29 if ( b.ut_type == USER_PROCESS ) {
31 // ut_user contains the username ..
32 // now we need to find the path to that account.
33 while ( ( pw = getpwent() ) ) {
35 if ( strcmp ( pw -> pw_name, b.ut_user ) == 0 ) {
38 strncpy ( r_username, b.ut_user, maxlen );
43 } // passwd entry matches the utmp entry
45 } // while iteratin across passwd entries
48 } // utmp entry is for a user login
58 // a generalized variable-substitution routine might be nice; for now we need a quick tilde one,
59 // so here goes. Brute force ftw!
60 char *pnd_expand_tilde ( char *freeable_buffer ) {
62 char *s = freeable_buffer;
63 char *home = getenv ( "HOME" );
65 //printf ( "expand tilde IN: '%s'\n", freeable_buffer );
66 //printf ( " home was %s\n", home );
68 // well, as pndnotifyd (etc) may be running as _root_, while the user is logged in
69 // as 'pandora' or god knows what, this could be problematic. Other parts of the lib
70 // use wordexp() for shell-like expansion, but this funciton is (at least) used by
71 // pndnotifyd for determination of the .desktop emit path, so we need ~ to expand
72 // to the _actual user_ rather than root's homedir. Rather than run 'users' or 'who'
73 // or the like, we'll just cut to the chase..
78 static char *florp = NULL;
81 f = fopen ( "/var/run/utmp", "r" );
85 while ( fread ( &b, sizeof(struct utmp), 1, f ) == 1 ) {
87 if ( b.ut_type == USER_PROCESS ) {
89 // ut_user contains the username ..
90 // now we need to find the path to that account.
91 while ( ( pw = getpwent() ) ) {
93 if ( strcmp ( pw -> pw_name, b.ut_user ) == 0 ) {
95 // aight, we've got a logged in user and have matched it to
96 // passwd entry, so can construct the appropriate path
101 florp = strdup ( pw -> pw_dir );
104 printf ( " DEBUG: home is %s (from %u)\n", home, b.ut_type );
106 } // passwd entry matches the utmp entry
108 } // while iteratin across passwd entries
111 } // utmp entry is for a user login
121 return ( s ); // can't succeed
124 printf ( "DEBUG: entering while (%s)\n", s );
126 while ( ( p = strchr ( s, '~' ) ) ) {
127 printf ( "DEBUG: within while (%s)\n", s );
128 char *temp = malloc ( strlen ( s ) + strlen ( home ) + 1 );
129 memset ( temp, '\0', strlen ( s ) + strlen ( home ) + 1 );
130 // copy in stuff prior to ~
131 strncpy ( temp, s, p - s );
133 strcat ( temp, home );
134 // copy stuff after tilde in
135 strcat ( temp, p + 1 );
139 } // while finding matches
141 printf ( "DEBUG: expand tilde OUT: '%s'\n", s );
146 void pnd_exec_no_wait_1 ( char *fullpath, char *arg1 ) {
149 if ( ( i = fork() ) < 0 ) {
150 printf ( "ERROR: Couldn't fork()\n" );
155 return; // parent process, don't care
158 // child process, do something
160 execl ( fullpath, fullpath, arg1, (char*) NULL );
162 execl ( fullpath, fullpath, (char*) NULL );
165 // getting here is an error
166 //printf ( "Error attempting to run %s\n", fullpath );
171 pnd_pxml_handle pnd_pxml_get_by_path ( char *fullpath ) {
172 unsigned char valid = pnd_object_type_unknown;
173 pnd_pxml_handle pxmlh = 0;
175 // WARN: this is way too close to callback in pnd_disco .. should be refactored!
177 if ( strcasestr ( fullpath, PXML_FILENAME ) ) {
178 valid = pnd_object_type_directory;
179 } else if ( strcasestr ( fullpath, PND_PACKAGE_FILEEXT "\0" ) ) {
180 valid = pnd_object_type_pnd;
183 // if not a file of interest, just keep looking until we run out
188 // potentially a valid application
189 if ( valid == pnd_object_type_directory ) {
190 pxmlh = pnd_pxml_fetch ( (char*) fullpath );
192 } else if ( valid == pnd_object_type_pnd ) {
194 char pxmlbuf [ 32 * 1024 ]; // TBD: assuming 32k pxml accrual buffer is a little lame
197 f = fopen ( fullpath, "r" );
199 // try to locate the PXML portion
200 if ( ! pnd_pnd_seek_pxml ( f ) ) {
202 return ( 0 ); // pnd or not, but not to spec. Pwn'd the pnd?
205 // accrue it into a buffer
206 if ( ! pnd_pnd_accrue_pxml ( f, pxmlbuf, 32 * 1024 ) ) {
211 // by now, we have <PXML> .. </PXML>, try to parse..
212 pxmlh = pnd_pxml_fetch_buffer ( (char*) fullpath, pxmlbuf );