Aesthetic changes to conf panel; minor fix to libpnd that no one but mmenu will notice.
[pandora-libraries.git] / lib / pnd_utility.c
index b7e146f..9647f20 100644 (file)
@@ -8,6 +8,8 @@
 #include <utmp.h> /* for expand-tilde below; see commentary for this about-turn */
 #include <sys/types.h> /* ditto */
 #include <pwd.h> /* ditto */
+#include <sys/stat.h> /* for fstat */
+#include <dirent.h> /* for opendir */
 
 #include "pnd_pxml.h"
 #include "pnd_container.h"
 #include "pnd_pndfiles.h"
 #include "pnd_discovery.h"
 
+unsigned char pnd_check_login ( char *r_username, unsigned int maxlen ) {
+  FILE *f;
+  struct utmp b;
+  struct passwd *pw;
+
+  f = fopen ( "/var/run/utmp", "r" );
+
+  if ( f ) {
+
+    // spin until a non-root user comes along
+    while ( fread ( &b, sizeof(struct utmp), 1, f ) == 1 ) {
+
+      if ( ( b.ut_type == USER_PROCESS ) &&
+          ( strcmp ( b.ut_user, "root" ) != 0 ) )
+      {
+
+       // ut_user contains the username ..
+       // now we need to find the path to that account.
+       while ( ( pw = getpwent() ) ) {
+
+         if ( strcmp ( pw -> pw_name, b.ut_user ) == 0 ) {
+
+           if ( r_username ) {
+             strncpy ( r_username, b.ut_user, maxlen );
+           }
+
+           fclose ( f );
+           return ( 1 );
+         } // passwd entry matches the utmp entry
+
+       } // while iteratin across passwd entries
+       endpwent();
+
+      } // utmp entry is for a user login
+
+    } // while
+
+    fclose ( f );
+  } // opened?
+
+  return ( 0 );
+}
+
 // a generalized variable-substitution routine might be nice; for now we need a quick tilde one,
 // so here goes. Brute force ftw!
 char *pnd_expand_tilde ( char *freeable_buffer ) {
@@ -22,8 +67,8 @@ char *pnd_expand_tilde ( char *freeable_buffer ) {
   char *s = freeable_buffer;
   char *home = getenv ( "HOME" );
 
-  //printf ( "expand tilde IN: '%s'\n", freeable_buffer );
-  //printf ( "  home was %s\n", home );
+  //printf ( "DEBUG: expand tilde IN: '%s'\n", freeable_buffer );
+  //printf ( "DEBUG:  $HOME was %s\n", home );
 
   // well, as pndnotifyd (etc) may be running as _root_, while the user is logged in
   // as 'pandora' or god knows what, this could be problematic. Other parts of the lib
@@ -61,7 +106,7 @@ char *pnd_expand_tilde ( char *freeable_buffer ) {
              florp = strdup ( pw -> pw_dir );
 
              home = florp;
-             //printf ( "  home is %s (from %u)\n", home, b.ut_type );
+             //printf ( "  DEBUG: home (for %s) is %s (from %u)\n", b.ut_user, home, b.ut_type );
 
            } // passwd entry matches the utmp entry
 
@@ -81,7 +126,10 @@ char *pnd_expand_tilde ( char *freeable_buffer ) {
     return ( s ); // can't succeed
   }
 
+  //printf ( "DEBUG: entering while (%s) with home (%s)\n", s, home );
+
   while ( ( p = strchr ( s, '~' ) ) ) {
+    //printf ( "DEBUG: within while (%s)\n", s );
     char *temp = malloc ( strlen ( s ) + strlen ( home ) + 1 );
     memset ( temp, '\0', strlen ( s ) + strlen ( home ) + 1 );
     // copy in stuff prior to ~
@@ -95,7 +143,7 @@ char *pnd_expand_tilde ( char *freeable_buffer ) {
     s = temp;
   } // while finding matches
 
-  //printf ( "expand tilde OUT: '%s'\n", s );
+  //printf ( "DEBUG: expand tilde OUT: '%s'\n", s );
 
   return ( s );
 }
@@ -119,15 +167,18 @@ void pnd_exec_no_wait_1 ( char *fullpath, char *arg1 ) {
     execl ( fullpath, fullpath, (char*) NULL );
   }
 
+  // error invoking something, and we're the child process, so just die before all hell breaks lose with us thinking we're the (second!) parent on return!
+  exit ( -1 );
+
   // getting here is an error
   //printf ( "Error attempting to run %s\n", fullpath );
 
   return;
 }
 
-pnd_pxml_handle pnd_pxml_get_by_path ( char *fullpath ) {
+pnd_pxml_handle *pnd_pxml_get_by_path ( char *fullpath ) {
   unsigned char valid = pnd_object_type_unknown;
-  pnd_pxml_handle pxmlh = 0;
+  pnd_pxml_handle *pxmlapps = 0;
 
   // WARN: this is way too close to callback in pnd_disco .. should be refactored!
 
@@ -144,7 +195,7 @@ pnd_pxml_handle pnd_pxml_get_by_path ( char *fullpath ) {
 
   // potentially a valid application
   if ( valid == pnd_object_type_directory ) {
-    pxmlh = pnd_pxml_fetch ( (char*) fullpath );
+    pxmlapps = pnd_pxml_fetch ( (char*) fullpath );
 
   } else if ( valid == pnd_object_type_pnd ) {
     FILE *f;
@@ -166,7 +217,7 @@ pnd_pxml_handle pnd_pxml_get_by_path ( char *fullpath ) {
     }
 
     // by now, we have <PXML> .. </PXML>, try to parse..
-    pxmlh = pnd_pxml_fetch_buffer ( (char*) fullpath, pxmlbuf );
+    pxmlapps = pnd_pxml_fetch_buffer ( (char*) fullpath, pxmlbuf );
 
     // done with file
     fclose ( f );
@@ -175,5 +226,138 @@ pnd_pxml_handle pnd_pxml_get_by_path ( char *fullpath ) {
 
   // ..
 
-  return ( pxmlh );
+  return ( pxmlapps );
+}
+
+unsigned char pnd_determine_mountpoint ( char *fullpath, char *r_mountpoint, unsigned int mountpoint_len ) {
+
+  // just cheap it, and call df like an idiot.
+
+  // Filesystem           1K-blocks      Used Available Use% Mounted on
+
+  char cmd [ PATH_MAX ];
+  FILE *p;
+  char inbuf [ PATH_MAX ];
+
+  sprintf ( cmd, "/bin/df %s 2>/dev/null", fullpath );
+
+  if ( ( p = popen ( cmd, "r" ) ) ) {
+
+    // ignore title line; we really shoudl analyze it to figure out which column, but we make assumptions..
+    fgets ( inbuf, PATH_MAX, p );
+
+    if ( ! fgets ( inbuf, PATH_MAX, p ) ) {
+      pclose ( p );
+      return ( 0 );
+    }
+
+    pclose ( p );
+
+    // by now, good
+    char mount [ PATH_MAX ];
+    if ( sscanf ( inbuf, "%*s %*s %*s %*s %*s %s", mount ) != 1 ) {
+      return ( 0 );
+    }
+
+    if ( strlen ( mount ) < mountpoint_len ) {
+      strcpy ( r_mountpoint, mount );
+      return ( 1 );
+    }
+
+  } // if popen
+
+  return ( 0 );
+
+#if 0
+  struct stat fooby;
+
+  // can we even stat this file?
+  if ( stat ( fullpath, &fooby ) == 0 ) {
+    //dev_t     st_dev;     /* ID of device containing file */
+    //dev_t     st_rdev;    /* device ID (if special file) */
+
+    dev_t mount = fooby.st_dev;
+
+    DIR *d = opendir ( "/dev" );
+
+    if ( d ) {
+      struct dirent *de;
+      char path [ FILENAME_MAX ];
+
+      while ( de = readdir ( d ) ) {
+       sprintf ( path, "/dev/%s", de -> d_name );
+
+       if ( stat ( path, &fooby ) == 0 ) {
+
+         // finally, if we find the same major/minor pair in /dev, as we found for the target file, it means we found the right device
+         if ( fooby.st_rdev == mount ) {
+           printf ( "Device: %s\n", path );
+         }
+
+       } // if
+
+      } // while
+
+    } // opened /dev?
+
+  } // stat
+#endif
+
+  return ( 0 );
+}
+
+unsigned char pnd_filecopy ( char *sourcepath, char *targetpath ) {
+#define BITLEN (64*1024)
+  FILE *pnd, *target; // pnd == from, since I cribbed the code from pnd_desktop.c :/
+  unsigned char bits [ BITLEN ];
+  unsigned int bitlen;
+
+  pnd = fopen ( sourcepath, "rb" );
+
+  if ( ! pnd ) {
+    return ( 0 );
+  }
+
+  unsigned int len;
+
+  target = fopen ( targetpath, "wb" );
+
+  if ( ! target ) {
+    fclose ( pnd );
+    return ( 0 );
+  }
+
+  fseek ( pnd, 0, SEEK_END );
+  len = ftell ( pnd );
+  fseek ( pnd, 0, SEEK_SET );
+
+  while ( len ) {
+
+    if ( len > (BITLEN) ) {
+      bitlen = (BITLEN);
+    } else {
+      bitlen = len;
+    }
+
+    if ( fread ( bits, bitlen, 1, pnd ) != 1 ) {
+      fclose ( pnd );
+      fclose ( target );
+      unlink ( targetpath );
+      return ( 0 );
+    }
+
+    if ( fwrite ( bits, bitlen, 1, target ) != 1 ) {
+      fclose ( pnd );
+      fclose ( target );
+      unlink ( targetpath );
+      return ( 0 );
+    }
+
+    len -= bitlen;
+  } // while
+
+  fclose ( pnd );
+  fclose ( target );
+
+  return ( 1 );
 }