Assists music production by grouping standalone programs into sessions. Community version of "Non Session Manager".
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

244 lines
5.1KB

  1. /*******************************************************************************/
  2. /* Copyright (C) 2008-2020 Jonathan Moore Liles (as "Non-Session-Manager") */
  3. /* Copyright (C) 2020- Nils Hilbricht */
  4. /* */
  5. /* This file is part of New-Session-Manager */
  6. /* */
  7. /* New-Session-Manager is free software: you can redistribute it and/or modify */
  8. /* it under the terms of the GNU General Public License as published by */
  9. /* the Free Software Foundation, either version 3 of the License, or */
  10. /* (at your option) any later version. */
  11. /* */
  12. /* New-Session-Manager is distributed in the hope that it will be useful, */
  13. /* but WITHOUT ANY WARRANTY; without even the implied warranty of */
  14. /* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
  15. /* GNU General Public License for more details. */
  16. /* */
  17. /* You should have received a copy of the GNU General Public License */
  18. /* along with New-Session-Manager. If not, see <https://www.gnu.org/licenses/>.*/
  19. /*******************************************************************************/
  20. #include <fcntl.h>
  21. #include <sys/stat.h>
  22. #include <sys/types.h>
  23. #include <unistd.h>
  24. #include <stdio.h>
  25. #include <string.h>
  26. #include <stdlib.h>
  27. #include <sys/vfs.h>
  28. unsigned long
  29. modification_time ( const char *file )
  30. {
  31. struct stat st;
  32. if ( stat( file, &st ) )
  33. return 0;
  34. return st.st_mtime;
  35. }
  36. /** returns /true/ if /file1/ is newer than /file2/ (or file2 doesn't exist) */
  37. bool
  38. newer ( const char *file1, const char *file2 )
  39. {
  40. return modification_time( file1 ) > modification_time( file2 );
  41. }
  42. unsigned long
  43. size ( const char *file )
  44. {
  45. struct stat st;
  46. if ( stat( file, &st ) )
  47. return 0;
  48. return st.st_size;
  49. }
  50. int
  51. exists ( const char *name )
  52. {
  53. struct stat st;
  54. return 0 == stat( name, &st );
  55. }
  56. bool
  57. acquire_lock ( int *lockfd, const char *filename )
  58. {
  59. struct flock fl;
  60. fl.l_type = F_WRLCK;
  61. fl.l_whence = SEEK_SET;
  62. fl.l_start = 0;
  63. fl.l_len = 0;
  64. *lockfd = ::creat( filename, 0777 );
  65. if ( fcntl( *lockfd, F_SETLK, &fl ) != 0 )
  66. return false;
  67. return true;
  68. }
  69. void
  70. release_lock ( int *lockfd, const char *filename )
  71. {
  72. unlink( filename );
  73. ::close( *lockfd );
  74. *lockfd = 0;
  75. }
  76. int
  77. backwards_fgetc ( FILE *fp )
  78. {
  79. int c;
  80. if ( fseek( fp, -1, SEEK_CUR ) != 0 )
  81. return -1;
  82. c = fgetc( fp );
  83. fseek( fp, -1, SEEK_CUR );
  84. return c;
  85. }
  86. char *
  87. backwards_afgets ( FILE *fp )
  88. {
  89. size_t size = 0;
  90. char *s = NULL;
  91. size_t i = 0;
  92. int c;
  93. while ( ( c = backwards_fgetc( fp ) ) >= 0 )
  94. {
  95. if ( i > 0 && '\n' == c )
  96. break;
  97. if ( i >= size )
  98. {
  99. size += 256;
  100. s = (char*)realloc( s, size );
  101. }
  102. s[i++] = c;
  103. }
  104. if ( s )
  105. {
  106. s[i] = 0;
  107. int len = strlen(s) ;
  108. int c, i, j;
  109. for (i = 0, j = len - 1; i < j; i++, j--)
  110. {
  111. c = s[i];
  112. s[i] = s[j];
  113. s[j] = c;
  114. }
  115. }
  116. fseek( fp, 1, SEEK_CUR );
  117. return s;
  118. }
  119. /** update the modification time of file referred to by /fd/ */
  120. void
  121. touch ( int fd )
  122. {
  123. struct stat st;
  124. fstat( fd, &st );
  125. fchmod( fd, st.st_mode );
  126. }
  127. /** write a single string to a file */
  128. void
  129. write_line ( const char *dir, const char *name, const char *value )
  130. {
  131. char path[512];
  132. snprintf( path, sizeof( path ), "%s/%s", dir, name );
  133. FILE *fp = fopen( path, "w" );
  134. if ( ! fp )
  135. return;
  136. fputs( value, fp );
  137. fclose( fp );
  138. }
  139. /** read a single string from a file */
  140. char *
  141. read_line ( const char *dir, const char *name )
  142. {
  143. char path[512];
  144. snprintf( path, sizeof( path ), "%s/%s", dir, name );
  145. FILE *fp = fopen( path, "r" );
  146. if ( ! fp )
  147. return 0;
  148. char *value = (char*)malloc( 512 );
  149. if ( ! fgets( value, 512, fp ) )
  150. value[0] = 0;
  151. fclose( fp );
  152. return value;
  153. }
  154. #include <sys/statvfs.h>
  155. /** return the number of blocks free on filesystem containing file named /file/ */
  156. fsblkcnt_t
  157. free_space ( const char *file )
  158. {
  159. struct statfs st;
  160. memset( &st, 0, sizeof( st ) );
  161. statfs( file, &st );
  162. return st.f_bavail;
  163. }
  164. /** return the total number of blocks on filesystem containing file named /file/ */
  165. fsblkcnt_t
  166. total_space ( const char *file )
  167. {
  168. struct statfs st;
  169. memset( &st, 0, sizeof( st ) );
  170. statfs( file, &st );
  171. return st.f_blocks;
  172. }
  173. /** return the percentage of usage on filesystem containing file named /file/ */
  174. int
  175. percent_used ( const char *file )
  176. {
  177. const double ts = total_space( file );
  178. const double fs = free_space( file );
  179. double percent_free = ( ( fs / ts ) * 100.0f );
  180. return (int) (100.0f - percent_free);
  181. }