From: <enl...@li...> - 2001-11-16 22:06:07
|
Enlightenment CVS committal Author : cpk Project : e17 Module : apps/efsd Dir : e17/apps/efsd/doc Modified Files: efsd-manual.sgml manual.raw Log Message: Doco fixlet, removed a printf in libefsd. =================================================================== RCS file: /cvsroot/enlightenment/e17/apps/efsd/doc/efsd-manual.sgml,v retrieving revision 1.21 retrieving revision 1.22 diff -u -3 -r1.21 -r1.22 --- efsd-manual.sgml 2001/10/23 21:42:08 1.21 +++ efsd-manual.sgml 2001/11/16 22:05:36 1.22 @@ -774,7 +774,7 @@ <title> When using <link linkend="API-efsd-metadata-get-str"><function> efsd_metadata_get_str()</function></link> or <link linkend="API-efsd-metadata-get-raw"> <function>efsd_metadata_get_raw()</function></link>, you need to <function>free()</function> - the string/data you receive. + the string/data you receive.</title> <para> This is because you get a copy of the data whenever you request it. Regardless of releasing this memory, you still need to call <link linkend="API-efsd-event-cleanup"> @@ -2620,6 +2620,45 @@ <para> Convenience function to access the command ID in reply or filechange events. Returns -1 if no ID is contained in the event. + </para> +</refsect1> +</refentry> + +<refentry> +<refmeta> +<refentrytitle><phrase id="API-efsd-reply-data">efsd_reply_data</phrase></refentrytitle> +</refmeta> +<refnamediv> + <refname>efsd_reply_data</refname> + <refpurpose> + returns data contained in a reply event + </refpurpose> +</refnamediv> +<refsynopsisdiv> + <title>Synopsis</title> + <funcsynopsis> + <funcdef>void * <function>efsd_reply_data </function></funcdef> + <paramdef>EfsdEvent * <parameter>ee</parameter></paramdef> + </funcsynopsis> +</refsynopsisdiv> +<refsect1> + <title>Arguments</title> + <variablelist> + <varlistentry> + <term><parameter>ee</parameter></term> + <listitem> + <para> + The EfsdEvent. + </para> + </listitem> + </varlistentry> + </variablelist> +</refsect1> +<refsect1> + <title>Description</title> + <para> + Convenience function access the data returned in a reply + event. Returns NULL if an error occured. </para> </refsect1> </refentry> =================================================================== RCS file: /cvsroot/enlightenment/e17/apps/efsd/doc/manual.raw,v retrieving revision 1.2 retrieving revision 1.3 diff -u -3 -r1.2 -r1.3 --- manual.raw 2001/10/23 21:42:08 1.2 +++ manual.raw 2001/11/16 22:05:36 1.3 @@ -774,7 +774,7 @@ <title> When using <link linkend="API-efsd-metadata-get-str"><function> efsd_metadata_get_str()</function></link> or <link linkend="API-efsd-metadata-get-raw"> <function>efsd_metadata_get_raw()</function></link>, you need to <function>free()</function> - the string/data you receive. + the string/data you receive.</title> <para> This is because you get a copy of the data whenever you request it. Regardless of releasing this memory, you still need to call <link linkend="API-efsd-event-cleanup"> |
From: <enl...@li...> - 2001-11-16 22:06:06
|
Enlightenment CVS committal Author : cpk Project : e17 Module : apps/efsd Dir : e17/apps/efsd/efsd Modified Files: libefsd.c Log Message: Doco fixlet, removed a printf in libefsd. =================================================================== RCS file: /cvsroot/enlightenment/e17/apps/efsd/efsd/libefsd.c,v retrieving revision 1.53 retrieving revision 1.54 diff -u -3 -r1.53 -r1.54 --- libefsd.c 2001/11/16 16:44:15 1.53 +++ libefsd.c 2001/11/16 22:05:36 1.54 @@ -252,8 +252,6 @@ cmd.efsd_set_metadata_cmd.key = strdup(key); cmd.efsd_set_metadata_cmd.file = get_full_path(filename); - printf("SENDING %s\n", cmd.efsd_set_metadata_cmd.file); - if (!cmd.efsd_set_metadata_cmd.file) goto error_return; |
From: <enl...@li...> - 2001-11-26 01:06:40
|
Enlightenment CVS committal Author : cpk Project : e17 Module : apps/efsd Dir : e17/apps/efsd/tools Modified Files: efsdsh.c Log Message: * Here's metadata monitoring. Details are in the manual and in libefsd's header file. * I'm using getpwuid() now instead of using $HOME to find a user's home directory. * The metadata access convenience calls in libefsd now behave as the manual says, i.e. they do not duplicate memory. Keep this in mind when you want to keep the data you receive around. * Updated doco accordingly. * Fixlets I cannot remember right now :) =================================================================== RCS file: /cvsroot/enlightenment/e17/apps/efsd/tools/efsdsh.c,v retrieving revision 1.20 retrieving revision 1.21 diff -u -3 -r1.20 -r1.21 --- efsdsh.c 2001/08/02 22:43:39 1.20 +++ efsdsh.c 2001/11/26 01:06:38 1.21 @@ -234,6 +234,10 @@ printf("Startmon event for dir %i\n", ee->efsd_reply_event.command.efsd_file_cmd.id); break; + case EFSD_CMD_STARTMON_META: + printf("Startmon event for metadata %i\n", + ee->efsd_reply_event.command.efsd_file_cmd.id); + break; case EFSD_CMD_STOPMON_FILE: printf("Stopmon event for file %i\n", ee->efsd_reply_event.command.efsd_file_cmd.id); @@ -242,6 +246,10 @@ printf("Stopmon event for dir %i\n", ee->efsd_reply_event.command.efsd_file_cmd.id); break; + case EFSD_CMD_STOPMON_META: + printf("Stopmon event for metadata %i\n", + ee->efsd_reply_event.command.efsd_file_cmd.id); + break; case EFSD_CMD_STAT: case EFSD_CMD_LSTAT: { @@ -307,6 +315,46 @@ } break; + case EFSD_EVENT_METADATA_CHANGE: + { + printf("Metadata change event %i on %s, key %s\n", + ee->efsd_metachange_event.id, + ee->efsd_metachange_event.file, + ee->efsd_metachange_event.key); + + switch (efsd_metadata_get_type(ee)) + { + case EFSD_INT: + { + int val; + + efsd_metadata_get_int(ee, &val); + printf("File: %s, key: %s --> val: %i\n", + efsd_metadata_get_file(ee), + efsd_metadata_get_key(ee), + val); + } + break; + case EFSD_FLOAT: + { + float val; + + efsd_metadata_get_float(ee, &val); + printf("File: %s, key: %s --> val: %f\n", + efsd_metadata_get_file(ee), + efsd_metadata_get_key(ee), + val); + } + break; + case EFSD_STRING: + printf("File: %s, key: %s --> val: %s\n", + efsd_metadata_get_file(ee), + efsd_metadata_get_key(ee), + efsd_metadata_get_str(ee)); + break; + default: + } + } default: } @@ -340,8 +388,10 @@ "ls <file> Shows directory contents\n" "mon_file <file> Starts monitoring file\n" "mon_dir <file> Starts monitoring dir\n" + "mon_meta <file> <key> Starts monitoring metadata\n" "stopmon_file <file> Stops monitoring file\n" "stopmon_dir <file> Stops monitoring dir\n" + "stopmon_meta <file> <key> Stops monitoring metadata\n" "gettype <file> Returns file type of file\n" "getstat <file> Returns result of stat on file.\n" "getlstat <file> Returns result of lstat on file.\n" @@ -697,6 +747,30 @@ { if ((id = efsd_stop_monitor(ec, tok, FALSE)) < 0) printf("Couldn't issue stopmon_file command.\n"); + } + } + else if (!strcmp(tok, "mon_meta")) + { + char *file; + char *key; + + if ((file = strtok(NULL, " \t\n")) && + (key = strtok(NULL, " \t\n"))) + { + if ((id = efsd_start_monitor_metadata(ec, file, key)) < 0) + printf("Couldn't issue mon_meta command.\n"); + } + } + else if (!strcmp(tok, "stopmon_meta")) + { + char *file; + char *key; + + if ((file = strtok(NULL, " \t\n")) && + (key = strtok(NULL, " \t\n"))) + { + if ((id = efsd_stop_monitor_metadata(ec, file, key)) < 0) + printf("Couldn't issue mon_meta command.\n"); } } else |
From: <enl...@li...> - 2001-11-26 01:07:10
|
Enlightenment CVS committal Author : cpk Project : e17 Module : apps/efsd Dir : e17/apps/efsd/doc/figures Modified Files: efsd-event.eps efsd-event.fig Log Message: * Here's metadata monitoring. Details are in the manual and in libefsd's header file. * I'm using getpwuid() now instead of using $HOME to find a user's home directory. * The metadata access convenience calls in libefsd now behave as the manual says, i.e. they do not duplicate memory. Keep this in mind when you want to keep the data you receive around. * Updated doco accordingly. * Fixlets I cannot remember right now :) =================================================================== RCS file: /cvsroot/enlightenment/e17/apps/efsd/doc/figures/efsd-event.eps,v retrieving revision 1.2 retrieving revision 1.3 diff -u -3 -r1.2 -r1.3 --- efsd-event.eps 2001/08/02 23:00:05 1.2 +++ efsd-event.eps 2001/11/26 01:06:38 1.3 @@ -1,9 +1,9 @@ %!PS-Adobe-2.0 EPSF-2.0 %%Title: efsd-event.eps %%Creator: fig2dev Version 3.2 Patchlevel 3d -%%CreationDate: Fri Aug 3 00:51:10 2001 +%%CreationDate: Sun Nov 25 01:14:15 2001 %%For: elwood@Gonzo (Elwood Blues,,,) -%%BoundingBox: 0 0 510 626 +%%BoundingBox: 0 0 510 1022 %%Magnification: 1.0000 %%EndComments /$F2psDict 200 dict def @@ -49,8 +49,8 @@ end save -newpath 0 626 moveto 0 0 lineto 510 0 lineto 510 626 lineto closepath clip newpath --72.9 774.6 translate +newpath 0 1022 moveto 0 0 lineto 510 0 lineto 510 1022 lineto closepath clip newpath +-72.9 1174.3 translate 1 -1 scale /cp {closepath} bind def @@ -95,38 +95,50 @@ % % Polyline 7.500 slw -n 1410 2430 m 1215 2430 1215 12090 195 arcto 4 {pop} repeat - 1215 12285 9035 12285 195 arcto 4 {pop} repeat - 9230 12285 9230 2625 195 arcto 4 {pop} repeat - 9230 2430 1410 2430 195 arcto 4 {pop} repeat +n 1410 3870 m 1215 3870 1215 18435 195 arcto 4 {pop} repeat + 1215 18630 9035 18630 195 arcto 4 {pop} repeat + 9230 18630 9230 4065 195 arcto 4 {pop} repeat + 9230 3870 1410 3870 195 arcto 4 {pop} repeat cp gs col32 1.00 shd ef gr gs col32 s gr % Polyline -n 1380 2385 m 1170 2385 1170 12030 210 arcto 4 {pop} repeat - 1170 12240 8975 12240 210 arcto 4 {pop} repeat - 9185 12240 9185 2595 210 arcto 4 {pop} repeat - 9185 2385 1380 2385 210 arcto 4 {pop} repeat +n 1380 2430 m 1170 2430 1170 18375 210 arcto 4 {pop} repeat + 1170 18585 8975 18585 210 arcto 4 {pop} repeat + 9185 18585 9185 2640 210 arcto 4 {pop} repeat + 9185 2430 1380 2430 210 arcto 4 {pop} repeat cp gs col33 1.00 shd ef gr gs col0 s gr /Courier-Bold ff 300.00 scf sf 1395 2745 m gs 1 -1 sc (EfsdEvent union) col0 sh gr % Polyline +n 1515 13958 m 1440 13958 1440 18420 75 arcto 4 {pop} repeat + 1440 18495 8896 18495 75 arcto 4 {pop} repeat + 8971 18495 8971 14033 75 arcto 4 {pop} repeat + 8971 13958 1515 13958 75 arcto 4 {pop} repeat + cp gs col32 1.00 shd ef gr gs col32 s gr +% Polyline n 1500 2933 m 1440 2933 1440 3405 60 arcto 4 {pop} repeat 1440 3465 8911 3465 60 arcto 4 {pop} repeat 8971 3465 8971 2993 60 arcto 4 {pop} repeat 8971 2933 1500 2933 60 arcto 4 {pop} repeat cp gs col32 1.00 shd ef gr gs col32 s gr % Polyline +n 1515 7073 m 1440 7073 1440 13650 75 arcto 4 {pop} repeat + 1440 13725 8896 13725 75 arcto 4 {pop} repeat + 8971 13725 8971 7148 75 arcto 4 {pop} repeat + 8971 7073 1515 7073 75 arcto 4 {pop} repeat + cp gs col32 1.00 shd ef gr gs col32 s gr +% Polyline n 1515 3645 m 1440 3645 1440 7260 75 arcto 4 {pop} repeat 1440 7335 8896 7335 75 arcto 4 {pop} repeat 8971 7335 8971 3720 75 arcto 4 {pop} repeat 8971 3645 1515 3645 75 arcto 4 {pop} repeat cp gs col32 1.00 shd ef gr gs col32 s gr % Polyline -n 1470 7568 m 1395 7568 1395 12030 75 arcto 4 {pop} repeat - 1395 12105 8896 12105 75 arcto 4 {pop} repeat - 8971 12105 8971 7643 75 arcto 4 {pop} repeat - 8971 7568 1470 7568 75 arcto 4 {pop} repeat - cp gs col32 1.00 shd ef gr gs col32 s gr +n 1470 13913 m 1395 13913 1395 18375 75 arcto 4 {pop} repeat + 1395 18450 8851 18450 75 arcto 4 {pop} repeat + 8926 18450 8926 13988 75 arcto 4 {pop} repeat + 8926 13913 1470 13913 75 arcto 4 {pop} repeat + cp gs col34 1.00 shd ef gr gs col0 s gr % Polyline n 1455 2880 m 1395 2880 1395 3352 60 arcto 4 {pop} repeat 1395 3412 8866 3412 60 arcto 4 {pop} repeat @@ -140,28 +152,70 @@ 8926 3600 1470 3600 75 arcto 4 {pop} repeat cp gs col34 1.00 shd ef gr gs col0 s gr % Polyline -n 1425 7523 m 1350 7523 1350 11985 75 arcto 4 {pop} repeat - 1350 12060 8851 12060 75 arcto 4 {pop} repeat - 8926 12060 8926 7598 75 arcto 4 {pop} repeat - 8926 7523 1425 7523 75 arcto 4 {pop} repeat +n 1470 7028 m 1395 7028 1395 13605 75 arcto 4 {pop} repeat + 1395 13680 8852 13680 75 arcto 4 {pop} repeat + 8927 13680 8927 7103 75 arcto 4 {pop} repeat + 8927 7028 1470 7028 75 arcto 4 {pop} repeat cp gs col34 1.00 shd ef gr gs col0 s gr +% Polyline +n 1678 9675 m 1618 9675 1618 10245 60 arcto 4 {pop} repeat + 1618 10305 8761 10305 60 arcto 4 {pop} repeat + 8821 10305 8821 9735 60 arcto 4 {pop} repeat + 8821 9675 1678 9675 60 arcto 4 {pop} repeat + cp gs col32 1.00 shd ef gr gs col32 s gr +% Polyline +n 1678 10485 m 1618 10485 1618 11055 60 arcto 4 {pop} repeat + 1618 11115 8761 11115 60 arcto 4 {pop} repeat + 8821 11115 8821 10545 60 arcto 4 {pop} repeat + 8821 10485 1678 10485 60 arcto 4 {pop} repeat + cp gs col32 1.00 shd ef gr gs col32 s gr +% Polyline +n 1678 11340 m 1618 11340 1618 11910 60 arcto 4 {pop} repeat + 1618 11970 8761 11970 60 arcto 4 {pop} repeat + 8821 11970 8821 11400 60 arcto 4 {pop} repeat + 8821 11340 1678 11340 60 arcto 4 {pop} repeat + cp gs col32 1.00 shd ef gr gs col32 s gr +% Polyline +n 1678 12150 m 1618 12150 1618 12720 60 arcto 4 {pop} repeat + 1618 12780 8761 12780 60 arcto 4 {pop} repeat + 8821 12780 8821 12210 60 arcto 4 {pop} repeat + 8821 12150 1678 12150 60 arcto 4 {pop} repeat + cp gs col32 1.00 shd ef gr gs col32 s gr +% Polyline +n 1678 12960 m 1618 12960 1618 13530 60 arcto 4 {pop} repeat + 1618 13590 8761 13590 60 arcto 4 {pop} repeat + 8821 13590 8821 13020 60 arcto 4 {pop} repeat + 8821 12960 1678 12960 60 arcto 4 {pop} repeat + cp gs col32 1.00 shd ef gr gs col32 s gr +% Polyline +n 1679 14445 m 1619 14445 1619 15015 60 arcto 4 {pop} repeat + 1619 15075 8761 15075 60 arcto 4 {pop} repeat + 8821 15075 8821 14505 60 arcto 4 {pop} repeat + 8821 14445 1679 14445 60 arcto 4 {pop} repeat + cp gs col32 1.00 shd ef gr gs col32 s gr +% Polyline +n 1679 15255 m 1619 15255 1619 15825 60 arcto 4 {pop} repeat + 1619 15885 8761 15885 60 arcto 4 {pop} repeat + 8821 15885 8821 15315 60 arcto 4 {pop} repeat + 8821 15255 1679 15255 60 arcto 4 {pop} repeat + cp gs col32 1.00 shd ef gr gs col32 s gr +% Polyline +n 1679 16065 m 1619 16065 1619 16635 60 arcto 4 {pop} repeat + 1619 16695 8761 16695 60 arcto 4 {pop} repeat + 8821 16695 8821 16125 60 arcto 4 {pop} repeat + 8821 16065 1679 16065 60 arcto 4 {pop} repeat + cp gs col32 1.00 shd ef gr gs col32 s gr +% Polyline +n 1679 16875 m 1619 16875 1619 17445 60 arcto 4 {pop} repeat + 1619 17505 8761 17505 60 arcto 4 {pop} repeat + 8821 17505 8821 16935 60 arcto 4 {pop} repeat + 8821 16875 1679 16875 60 arcto 4 {pop} repeat + cp gs col32 1.00 shd ef gr gs col32 s gr % Polyline -n 1635 9675 m 1575 9675 1575 10245 60 arcto 4 {pop} repeat - 1575 10305 8760 10305 60 arcto 4 {pop} repeat - 8820 10305 8820 9735 60 arcto 4 {pop} repeat - 8820 9675 1635 9675 60 arcto 4 {pop} repeat - cp gs col32 1.00 shd ef gr gs col32 s gr -% Polyline -n 1635 10485 m 1575 10485 1575 11055 60 arcto 4 {pop} repeat - 1575 11115 8760 11115 60 arcto 4 {pop} repeat - 8820 11115 8820 10545 60 arcto 4 {pop} repeat - 8820 10485 1635 10485 60 arcto 4 {pop} repeat - cp gs col32 1.00 shd ef gr gs col32 s gr -% Polyline -n 1635 11295 m 1575 11295 1575 11865 60 arcto 4 {pop} repeat - 1575 11925 8760 11925 60 arcto 4 {pop} repeat - 8820 11925 8820 11355 60 arcto 4 {pop} repeat - 8820 11295 1635 11295 60 arcto 4 {pop} repeat +n 1679 17685 m 1619 17685 1619 18255 60 arcto 4 {pop} repeat + 1619 18315 8761 18315 60 arcto 4 {pop} repeat + 8821 18315 8821 17745 60 arcto 4 {pop} repeat + 8821 17685 1679 17685 60 arcto 4 {pop} repeat cp gs col32 1.00 shd ef gr gs col32 s gr % Polyline n 1635 4095 m 1575 4095 1575 4665 60 arcto 4 {pop} repeat @@ -188,36 +242,78 @@ 8820 5715 1635 5715 60 arcto 4 {pop} repeat cp gs col32 1.00 shd ef gr gs col32 s gr % Polyline -n 1635 8055 m 1575 8055 1575 8625 60 arcto 4 {pop} repeat - 1575 8685 8760 8685 60 arcto 4 {pop} repeat - 8820 8685 8820 8115 60 arcto 4 {pop} repeat - 8820 8055 1635 8055 60 arcto 4 {pop} repeat - cp gs col32 1.00 shd ef gr gs col32 s gr +n 1678 8055 m 1618 8055 1618 8625 60 arcto 4 {pop} repeat + 1618 8685 8761 8685 60 arcto 4 {pop} repeat + 8821 8685 8821 8115 60 arcto 4 {pop} repeat + 8821 8055 1678 8055 60 arcto 4 {pop} repeat + cp gs col32 1.00 shd ef gr gs col32 s gr +% Polyline +n 1678 8865 m 1618 8865 1618 9435 60 arcto 4 {pop} repeat + 1618 9495 8761 9495 60 arcto 4 {pop} repeat + 8821 9495 8821 8925 60 arcto 4 {pop} repeat + 8821 8865 1678 8865 60 arcto 4 {pop} repeat + cp gs col32 1.00 shd ef gr gs col32 s gr +% Polyline +n 1634 9630 m 1574 9630 1574 10200 60 arcto 4 {pop} repeat + 1574 10260 8717 10260 60 arcto 4 {pop} repeat + 8777 10260 8777 9690 60 arcto 4 {pop} repeat + 8777 9630 1634 9630 60 arcto 4 {pop} repeat + cp gs col7 1.00 shd ef gr gs col0 s gr % Polyline -n 1635 8865 m 1575 8865 1575 9435 60 arcto 4 {pop} repeat - 1575 9495 8760 9495 60 arcto 4 {pop} repeat - 8820 9495 8820 8925 60 arcto 4 {pop} repeat - 8820 8865 1635 8865 60 arcto 4 {pop} repeat - cp gs col32 1.00 shd ef gr gs col32 s gr +n 1634 10440 m 1574 10440 1574 11010 60 arcto 4 {pop} repeat + 1574 11070 8717 11070 60 arcto 4 {pop} repeat + 8777 11070 8777 10500 60 arcto 4 {pop} repeat + 8777 10440 1634 10440 60 arcto 4 {pop} repeat + cp gs col7 1.00 shd ef gr gs col0 s gr +% Polyline +n 1634 11295 m 1574 11295 1574 11865 60 arcto 4 {pop} repeat + 1574 11925 8717 11925 60 arcto 4 {pop} repeat + 8777 11925 8777 11355 60 arcto 4 {pop} repeat + 8777 11295 1634 11295 60 arcto 4 {pop} repeat + cp gs col7 1.00 shd ef gr gs col0 s gr +% Polyline +n 1634 12105 m 1574 12105 1574 12675 60 arcto 4 {pop} repeat + 1574 12735 8717 12735 60 arcto 4 {pop} repeat + 8777 12735 8777 12165 60 arcto 4 {pop} repeat + 8777 12105 1634 12105 60 arcto 4 {pop} repeat + cp gs col7 1.00 shd ef gr gs col0 s gr % Polyline -n 1590 9630 m 1530 9630 1530 10200 60 arcto 4 {pop} repeat - 1530 10260 8715 10260 60 arcto 4 {pop} repeat - 8775 10260 8775 9690 60 arcto 4 {pop} repeat - 8775 9630 1590 9630 60 arcto 4 {pop} repeat +n 1634 12915 m 1574 12915 1574 13485 60 arcto 4 {pop} repeat + 1574 13545 8717 13545 60 arcto 4 {pop} repeat + 8777 13545 8777 12975 60 arcto 4 {pop} repeat + 8777 12915 1634 12915 60 arcto 4 {pop} repeat cp gs col7 1.00 shd ef gr gs col0 s gr % Polyline -n 1590 10440 m 1530 10440 1530 11010 60 arcto 4 {pop} repeat - 1530 11070 8715 11070 60 arcto 4 {pop} repeat - 8775 11070 8775 10500 60 arcto 4 {pop} repeat - 8775 10440 1590 10440 60 arcto 4 {pop} repeat +n 1634 15210 m 1574 15210 1574 15780 60 arcto 4 {pop} repeat + 1574 15840 8716 15840 60 arcto 4 {pop} repeat + 8776 15840 8776 15270 60 arcto 4 {pop} repeat + 8776 15210 1634 15210 60 arcto 4 {pop} repeat cp gs col7 1.00 shd ef gr gs col0 s gr % Polyline -n 1590 11250 m 1530 11250 1530 11820 60 arcto 4 {pop} repeat - 1530 11880 8715 11880 60 arcto 4 {pop} repeat - 8775 11880 8775 11310 60 arcto 4 {pop} repeat - 8775 11250 1590 11250 60 arcto 4 {pop} repeat +n 1634 14400 m 1574 14400 1574 14970 60 arcto 4 {pop} repeat + 1574 15030 8716 15030 60 arcto 4 {pop} repeat + 8776 15030 8776 14460 60 arcto 4 {pop} repeat + 8776 14400 1634 14400 60 arcto 4 {pop} repeat cp gs col7 1.00 shd ef gr gs col0 s gr % Polyline +n 1634 16020 m 1574 16020 1574 16590 60 arcto 4 {pop} repeat + 1574 16650 8716 16650 60 arcto 4 {pop} repeat + 8776 16650 8776 16080 60 arcto 4 {pop} repeat + 8776 16020 1634 16020 60 arcto 4 {pop} repeat + cp gs col7 1.00 shd ef gr gs col0 s gr +% Polyline +n 1634 16830 m 1574 16830 1574 17400 60 arcto 4 {pop} repeat + 1574 17460 8716 17460 60 arcto 4 {pop} repeat + 8776 17460 8776 16890 60 arcto 4 {pop} repeat + 8776 16830 1634 16830 60 arcto 4 {pop} repeat + cp gs col7 1.00 shd ef gr gs col0 s gr +% Polyline +n 1634 17640 m 1574 17640 1574 18210 60 arcto 4 {pop} repeat + 1574 18270 8716 18270 60 arcto 4 {pop} repeat + 8776 18270 8776 17700 60 arcto 4 {pop} repeat + 8776 17640 1634 17640 60 arcto 4 {pop} repeat + cp gs col7 1.00 shd ef gr gs col0 s gr +% Polyline n 1590 6480 m 1530 6480 1530 7050 60 arcto 4 {pop} repeat 1530 7110 8715 7110 60 arcto 4 {pop} repeat 8775 7110 8775 6540 60 arcto 4 {pop} repeat @@ -242,68 +338,110 @@ 8775 4050 1590 4050 60 arcto 4 {pop} repeat cp gs col7 1.00 shd ef gr gs col0 s gr % Polyline -n 1590 8820 m 1530 8820 1530 9390 60 arcto 4 {pop} repeat - 1530 9450 8715 9450 60 arcto 4 {pop} repeat - 8775 9450 8775 8880 60 arcto 4 {pop} repeat - 8775 8820 1590 8820 60 arcto 4 {pop} repeat +n 1634 8820 m 1574 8820 1574 9390 60 arcto 4 {pop} repeat + 1574 9450 8717 9450 60 arcto 4 {pop} repeat + 8777 9450 8777 8880 60 arcto 4 {pop} repeat + 8777 8820 1634 8820 60 arcto 4 {pop} repeat cp gs col7 1.00 shd ef gr gs col0 s gr % Polyline -n 1590 8010 m 1530 8010 1530 8580 60 arcto 4 {pop} repeat - 1530 8640 8715 8640 60 arcto 4 {pop} repeat - 8775 8640 8775 8070 60 arcto 4 {pop} repeat - 8775 8010 1590 8010 60 arcto 4 {pop} repeat +n 1634 8010 m 1574 8010 1574 8580 60 arcto 4 {pop} repeat + 1574 8640 8717 8640 60 arcto 4 {pop} repeat + 8777 8640 8777 8070 60 arcto 4 {pop} repeat + 8777 8010 1634 8010 60 arcto 4 {pop} repeat cp gs col7 1.00 shd ef gr gs col0 s gr /Courier-Bold ff 300.00 scf sf +1574 14265 m +gs 1 -1 sc (EfsdReplyEvent) col0 sh gr +/Courier ff 300.00 scf sf +6003 14265 m +gs 1 -1 sc (efsd_reply_event) col0 sh gr +/Courier-Bold ff 300.00 scf sf 1530 3915 m gs 1 -1 sc (EfsdFileChangeEvent) col0 sh gr /Courier-Bold ff 300.00 scf sf -1530 7875 m -gs 1 -1 sc (EfsdReplyEvent) col0 sh gr -/Courier-Bold ff 300.00 scf sf 1530 3240 m gs 1 -1 sc (EfsdEventType) col0 sh gr /Courier ff 300.00 scf sf 5085 3915 m gs 1 -1 sc (efsd_filechange_event) col0 sh gr /Courier ff 300.00 scf sf -5985 7875 m -gs 1 -1 sc (efsd_reply_event) col0 sh gr -/Courier ff 300.00 scf sf 8100 3240 m gs 1 -1 sc (type) col0 sh gr /Courier-Bold ff 300.00 scf sf +1574 7875 m +gs 1 -1 sc (EfsdMetadataChangeEvent) col0 sh gr +/Courier ff 300.00 scf sf +5400 7875 m +gs 1 -1 sc (efsd_metachange_event) col0 sh gr +/Courier-Bold ff 300.00 scf sf +1665 10035 m +gs 1 -1 sc (char *) col0 sh gr +/Courier ff 300.00 scf sf +8145 10035 m +gs 1 -1 sc (key) col0 sh gr +/Courier-Bold ff 300.00 scf sf 1665 10845 m +gs 1 -1 sc (char *) col0 sh gr +/Courier ff 300.00 scf sf +8010 10845 m +gs 1 -1 sc (file) col0 sh gr +/Courier-Bold ff 300.00 scf sf +1665 11700 m +gs 1 -1 sc (EfsdDatatype) col0 sh gr +/Courier ff 300.00 scf sf +7335 11700 m +gs 1 -1 sc (datatype) col0 sh gr +/Courier-Bold ff 300.00 scf sf +1708 12510 m gs 1 -1 sc (int) col0 sh gr /Courier-Bold ff 300.00 scf sf -1665 10035 m +1708 13320 m +gs 1 -1 sc (void *) col0 sh gr +/Courier ff 300.00 scf sf +7971 13320 m +gs 1 -1 sc (data) col0 sh gr +/Courier ff 300.00 scf sf +7300 12510 m +gs 1 -1 sc (data_len) col0 sh gr +/Courier-Bold ff 300.00 scf sf +1708 14805 m +gs 1 -1 sc (EfsdEventType) col0 sh gr +/Courier-Bold ff 300.00 scf sf +1708 15615 m +gs 1 -1 sc (EfsdCommand) col0 sh gr +/Courier ff 300.00 scf sf +7971 14805 m +gs 1 -1 sc (type) col0 sh gr +/Courier ff 300.00 scf sf +7479 15615 m +gs 1 -1 sc (command) col0 sh gr +/Courier-Bold ff 300.00 scf sf +1708 17235 m +gs 1 -1 sc (int) col0 sh gr +/Courier-Bold ff 300.00 scf sf +1708 16425 m gs 1 -1 sc (int) col0 sh gr /Courier-Bold ff 300.00 scf sf -1665 11655 m +1708 18045 m gs 1 -1 sc (void *) col0 sh gr /Courier ff 300.00 scf sf -7290 10845 m +7300 17235 m gs 1 -1 sc (data_len) col0 sh gr /Courier ff 300.00 scf sf -7965 11655 m +7971 18045 m gs 1 -1 sc (data) col0 sh gr /Courier ff 300.00 scf sf -7110 10035 m +7121 16425 m gs 1 -1 sc (errorcode) col0 sh gr /Courier-Bold ff 300.00 scf sf 1665 4455 m gs 1 -1 sc (EfsdEventType) col0 sh gr /Courier-Bold ff 300.00 scf sf -1665 8415 m -gs 1 -1 sc (EfsdEventType) col0 sh gr -/Courier-Bold ff 300.00 scf sf 1665 5265 m gs 1 -1 sc (EfsdCmdId) col0 sh gr /Courier-Bold ff 300.00 scf sf 1665 6075 m gs 1 -1 sc (EfsdFilechangeType) col0 sh gr -/Courier-Bold ff 300.00 scf sf -1665 9225 m -gs 1 -1 sc (EfsdCommand) col0 sh gr /Courier ff 300.00 scf sf 8010 4455 m gs 1 -1 sc (type) col0 sh gr @@ -316,14 +454,20 @@ /Courier ff 300.00 scf sf 8010 6885 m gs 1 -1 sc (file) col0 sh gr -/Courier ff 300.00 scf sf -7965 8415 m -gs 1 -1 sc (type) col0 sh gr -/Courier ff 300.00 scf sf -7470 9225 m -gs 1 -1 sc (command) col0 sh gr /Courier-Bold ff 300.00 scf sf 1665 6885 m gs 1 -1 sc (char *) col0 sh gr +/Courier-Bold ff 300.00 scf sf +1708 8415 m +gs 1 -1 sc (EfsdEventType) col0 sh gr +/Courier ff 300.00 scf sf +7971 8415 m +gs 1 -1 sc (type) col0 sh gr +/Courier-Bold ff 300.00 scf sf +1710 9225 m +gs 1 -1 sc (EfsdCmdId) col0 sh gr +/Courier ff 300.00 scf sf +8280 9225 m +gs 1 -1 sc (id) col0 sh gr $F2psEnd rs =================================================================== RCS file: /cvsroot/enlightenment/e17/apps/efsd/doc/figures/efsd-event.fig,v retrieving revision 1.2 retrieving revision 1.3 diff -u -3 -r1.2 -r1.3 --- efsd-event.fig 2001/08/02 23:00:05 1.2 +++ efsd-event.fig 2001/11/26 01:06:38 1.3 @@ -11,29 +11,81 @@ 0 33 #e0e0e0 0 34 #f0f0f0 0 35 #eaeaea -6 1215 2430 9270 12285 -2 4 0 1 32 32 52 0 20 0.000 0 0 13 0 0 5 - 9230 12285 1215 12285 1215 2430 9230 2430 9230 12285 +6 1530 9630 8865 10305 +2 4 0 1 0 7 30 0 20 0.000 0 0 4 0 0 5 + 8777 10260 1574 10260 1574 9630 8777 9630 8777 10260 +2 4 0 1 32 32 32 0 20 0.000 0 0 4 0 0 5 + 8821 10305 1618 10305 1618 9675 8821 9675 8821 10305 +4 0 0 10 0 14 20 0.0000 4 180 990 1665 10035 char *\001 +4 0 0 10 0 12 20 0.0000 4 240 495 8145 10035 key\001 +-6 +6 1530 10440 8865 11115 +2 4 0 1 0 7 30 0 20 0.000 0 0 4 0 0 5 + 8777 11070 1574 11070 1574 10440 8777 10440 8777 11070 +2 4 0 1 32 32 32 0 20 0.000 0 0 4 0 0 5 + 8821 11115 1618 11115 1618 10485 8821 10485 8821 11115 +4 0 0 10 0 14 20 0.0000 4 180 990 1665 10845 char *\001 +4 0 0 10 0 12 20 0.0000 4 180 660 8010 10845 file\001 -6 -6 1530 9630 8820 11925 +6 1530 11295 8865 11970 2 4 0 1 0 7 30 0 20 0.000 0 0 4 0 0 5 - 8775 10260 1530 10260 1530 9630 8775 9630 8775 10260 + 8777 11925 1574 11925 1574 11295 8777 11295 8777 11925 +2 4 0 1 32 32 32 0 20 0.000 0 0 4 0 0 5 + 8821 11970 1618 11970 1618 11340 8821 11340 8821 11970 +4 0 0 10 0 14 20 0.0000 4 240 1980 1665 11700 EfsdDatatype\001 +4 0 0 10 0 12 20 0.0000 4 240 1320 7335 11700 datatype\001 +-6 +6 1530 12105 8865 13590 2 4 0 1 0 7 30 0 20 0.000 0 0 4 0 0 5 - 8775 11070 1530 11070 1530 10440 8775 10440 8775 11070 + 8777 12735 1574 12735 1574 12105 8777 12105 8777 12735 2 4 0 1 0 7 30 0 20 0.000 0 0 4 0 0 5 - 8775 11880 1530 11880 1530 11250 8775 11250 8775 11880 + 8777 13545 1574 13545 1574 12915 8777 12915 8777 13545 2 4 0 1 32 32 32 0 20 0.000 0 0 4 0 0 5 - 8820 10305 1575 10305 1575 9675 8820 9675 8820 10305 + 8821 12780 1618 12780 1618 12150 8821 12150 8821 12780 2 4 0 1 32 32 32 0 20 0.000 0 0 4 0 0 5 - 8820 11115 1575 11115 1575 10485 8820 10485 8820 11115 + 8821 13590 1618 13590 1618 12960 8821 12960 8821 13590 +4 0 0 10 0 14 20 0.0000 4 179 492 1708 12510 int\001 +4 0 0 10 0 14 20 0.0000 4 179 984 1708 13320 void *\001 +4 0 0 10 0 12 20 0.0000 4 179 656 7971 13320 data\001 +4 0 0 10 0 12 20 0.0000 4 238 1312 7300 12510 data_len\001 +-6 +6 1395 13905 9000 18495 +2 4 0 1 0 7 30 0 20 0.000 0 0 4 0 0 5 + 8776 15840 1574 15840 1574 15210 8776 15210 8776 15840 +2 4 0 1 0 7 30 0 20 0.000 0 0 4 0 0 5 + 8776 15030 1574 15030 1574 14400 8776 14400 8776 15030 +2 4 0 1 32 32 32 0 20 0.000 0 0 4 0 0 5 + 8821 15075 1619 15075 1619 14445 8821 14445 8821 15075 2 4 0 1 32 32 32 0 20 0.000 0 0 4 0 0 5 - 8820 11925 1575 11925 1575 11295 8820 11295 8820 11925 -4 0 0 10 0 14 20 0.0000 4 180 495 1665 10845 int\001 -4 0 0 10 0 14 20 0.0000 4 180 495 1665 10035 int\001 -4 0 0 10 0 14 20 0.0000 4 180 990 1665 11655 void *\001 -4 0 0 10 0 12 20 0.0000 4 240 1320 7290 10845 data_len\001 -4 0 0 10 0 12 20 0.0000 4 180 660 7965 11655 data\001 -4 0 0 10 0 12 20 0.0000 4 180 1485 7110 10035 errorcode\001 + 8821 15885 1619 15885 1619 15255 8821 15255 8821 15885 +2 4 0 1 32 32 42 0 20 0.000 0 0 5 0 0 5 + 8971 18495 1440 18495 1440 13958 8971 13958 8971 18495 +2 4 0 1 0 34 40 0 20 0.000 0 0 5 0 0 5 + 8926 18450 1395 18450 1395 13913 8926 13913 8926 18450 +2 4 0 1 0 7 30 0 20 0.000 0 0 4 0 0 5 + 8776 16650 1574 16650 1574 16020 8776 16020 8776 16650 +2 4 0 1 0 7 30 0 20 0.000 0 0 4 0 0 5 + 8776 17460 1574 17460 1574 16830 8776 16830 8776 17460 +2 4 0 1 0 7 30 0 20 0.000 0 0 4 0 0 5 + 8776 18270 1574 18270 1574 17640 8776 17640 8776 18270 +2 4 0 1 32 32 32 0 20 0.000 0 0 4 0 0 5 + 8821 16695 1619 16695 1619 16065 8821 16065 8821 16695 +2 4 0 1 32 32 32 0 20 0.000 0 0 4 0 0 5 + 8821 17505 1619 17505 1619 16875 8821 16875 8821 17505 +2 4 0 1 32 32 32 0 20 0.000 0 0 4 0 0 5 + 8821 18315 1619 18315 1619 17685 8821 17685 8821 18315 +4 0 0 20 0 14 20 0.0000 4 239 2296 1574 14265 EfsdReplyEvent\001 +4 0 0 10 0 14 20 0.0000 4 239 2132 1708 14805 EfsdEventType\001 +4 0 0 10 0 14 20 0.0000 4 179 1804 1708 15615 EfsdCommand\001 +4 0 0 20 0 12 20 0.0000 4 239 2624 6003 14265 efsd_reply_event\001 +4 0 0 10 0 12 20 0.0000 4 224 656 7971 14805 type\001 +4 0 0 10 0 12 20 0.0000 4 179 1148 7479 15615 command\001 +4 0 0 10 0 14 20 0.0000 4 179 492 1708 17235 int\001 +4 0 0 10 0 14 20 0.0000 4 179 492 1708 16425 int\001 +4 0 0 10 0 14 20 0.0000 4 179 984 1708 18045 void *\001 +4 0 0 10 0 12 20 0.0000 4 239 1312 7300 17235 data_len\001 +4 0 0 10 0 12 20 0.0000 4 179 656 7971 18045 data\001 +4 0 0 10 0 12 20 0.0000 4 179 1476 7121 16425 errorcode\001 -6 2 4 0 1 0 7 30 0 20 0.000 0 0 4 0 0 5 8775 7110 1530 7110 1530 6480 8775 6480 8775 7110 @@ -47,14 +99,8 @@ 8926 3412 1395 3412 1395 2880 8926 2880 8926 3412 2 4 0 1 0 34 40 0 20 0.000 0 0 5 0 0 5 8926 7290 1395 7290 1395 3600 8926 3600 8926 7290 -2 4 0 1 0 7 30 0 20 0.000 0 0 4 0 0 5 - 8775 9450 1530 9450 1530 8820 8775 8820 8775 9450 -2 4 0 1 0 7 30 0 20 0.000 0 0 4 0 0 5 - 8775 8640 1530 8640 1530 8010 8775 8010 8775 8640 2 4 0 1 32 32 42 0 20 0.000 0 0 4 0 0 5 8971 3465 1440 3465 1440 2933 8971 2933 8971 3465 -2 4 0 1 32 32 42 0 20 0.000 0 0 5 0 0 5 - 8971 7335 1440 7335 1440 3645 8971 3645 8971 7335 2 4 0 1 32 32 32 0 20 0.000 0 0 4 0 0 5 8820 4725 1575 4725 1575 4095 8820 4095 8820 4725 2 4 0 1 32 32 32 0 20 0.000 0 0 4 0 0 5 @@ -63,32 +109,40 @@ 8820 7155 1575 7155 1575 6525 8820 6525 8820 7155 2 4 0 1 32 32 32 0 20 0.000 0 0 4 0 0 5 8820 6345 1575 6345 1575 5715 8820 5715 8820 6345 +2 4 0 1 0 7 30 0 20 0.000 0 0 4 0 0 5 + 8777 9450 1574 9450 1574 8820 8777 8820 8777 9450 +2 4 0 1 0 7 30 0 20 0.000 0 0 4 0 0 5 + 8777 8640 1574 8640 1574 8010 8777 8010 8777 8640 2 4 0 1 32 32 32 0 20 0.000 0 0 4 0 0 5 - 8820 8685 1575 8685 1575 8055 8820 8055 8820 8685 + 8821 8685 1618 8685 1618 8055 8821 8055 8821 8685 2 4 0 1 32 32 32 0 20 0.000 0 0 4 0 0 5 - 8820 9495 1575 9495 1575 8865 8820 8865 8820 9495 -2 4 0 1 32 32 42 0 20 0.000 0 0 5 0 0 5 - 8971 12105 1395 12105 1395 7568 8971 7568 8971 12105 + 8821 9495 1618 9495 1618 8865 8821 8865 8821 9495 2 4 0 1 0 34 40 0 20 0.000 0 0 5 0 0 5 - 8926 12060 1350 12060 1350 7523 8926 7523 8926 12060 + 8927 13680 1395 13680 1395 7028 8927 7028 8927 13680 +2 4 0 1 32 32 42 0 20 0.000 0 0 5 0 0 5 + 8971 13725 1440 13725 1440 7073 8971 7073 8971 13725 +2 4 0 1 32 32 52 0 20 0.000 0 0 13 0 0 5 + 9230 18630 1215 18630 1215 3870 9230 3870 9230 18630 +2 4 0 1 32 32 42 0 20 0.000 0 0 5 0 0 5 + 8971 7335 1440 7335 1440 3645 8971 3645 8971 7335 2 4 0 1 0 33 50 0 20 0.000 0 0 14 0 0 5 - 9185 12240 1170 12240 1170 2385 9185 2385 9185 12240 + 9185 18585 1170 18585 1170 2430 9185 2430 9185 18585 4 0 0 20 0 14 20 0.0000 4 240 3135 1530 3915 EfsdFileChangeEvent\001 -4 0 0 20 0 14 20 0.0000 4 240 2310 1530 7875 EfsdReplyEvent\001 4 0 0 10 0 14 20 0.0000 4 240 2145 1665 4455 EfsdEventType\001 -4 0 0 10 0 14 20 0.0000 4 240 2145 1665 8415 EfsdEventType\001 4 0 0 10 0 14 20 0.0000 4 180 1485 1665 5265 EfsdCmdId\001 4 0 0 10 0 14 20 0.0000 4 240 2970 1665 6075 EfsdFilechangeType\001 -4 0 0 10 0 14 20 0.0000 4 180 1815 1665 9225 EfsdCommand\001 4 0 0 20 0 14 20 0.0000 4 240 2145 1530 3240 EfsdEventType\001 4 0 0 20 0 12 20 0.0000 4 240 3465 5085 3915 efsd_filechange_event\001 4 0 0 10 0 12 20 0.0000 4 225 660 8010 4455 type\001 4 0 0 10 0 12 20 0.0000 4 180 330 8325 5265 id\001 4 0 0 10 0 12 20 0.0000 4 240 1650 6930 6075 changetype\001 4 0 0 10 0 12 20 0.0000 4 180 660 8010 6885 file\001 -4 0 0 20 0 12 20 0.0000 4 240 2640 5985 7875 efsd_reply_event\001 -4 0 0 10 0 12 20 0.0000 4 225 660 7965 8415 type\001 -4 0 0 10 0 12 20 0.0000 4 180 1155 7470 9225 command\001 4 0 0 20 0 12 20 0.0000 4 225 660 8100 3240 type\001 4 0 0 10 0 14 20 0.0000 4 180 990 1665 6885 char *\001 4 0 0 50 0 14 20 0.0000 4 180 2475 1395 2745 EfsdEvent union\001 +4 0 0 10 0 14 20 0.0000 4 238 2133 1708 8415 EfsdEventType\001 +4 0 0 10 0 12 20 0.0000 4 223 656 7971 8415 type\001 +4 0 0 20 0 14 20 0.0000 4 240 3795 1574 7875 EfsdMetadataChangeEvent\001 +4 0 0 10 0 14 20 0.0000 4 180 1485 1710 9225 EfsdCmdId\001 +4 0 0 10 0 12 20 0.0000 4 180 330 8280 9225 id\001 +4 0 0 20 0 12 20 0.0000 4 240 3465 5400 7875 efsd_metachange_event\001 |
From: <enl...@li...> - 2001-11-26 01:07:10
|
Enlightenment CVS committal Author : cpk Project : e17 Module : apps/efsd Dir : e17/apps/efsd/efsd Modified Files: Makefile.am efsd.h efsd_commands.c efsd_commands.h efsd_filetype.c efsd_io.c efsd_list.c efsd_main.c efsd_meta.c efsd_meta.h efsd_misc.c efsd_misc.h efsd_monitor.c efsd_monitor.h efsd_stack.c efsd_types.c libefsd.c libefsd.h libefsd_misc.c Added Files: efsd_meta_monitor.c efsd_meta_monitor.h Log Message: * Here's metadata monitoring. Details are in the manual and in libefsd's header file. * I'm using getpwuid() now instead of using $HOME to find a user's home directory. * The metadata access convenience calls in libefsd now behave as the manual says, i.e. they do not duplicate memory. Keep this in mind when you want to keep the data you receive around. * Updated doco accordingly. * Fixlets I cannot remember right now :) =================================================================== RCS file: /cvsroot/enlightenment/e17/apps/efsd/efsd/Makefile.am,v retrieving revision 1.27 retrieving revision 1.28 diff -u -3 -r1.27 -r1.28 --- Makefile.am 2001/10/12 17:31:47 1.27 +++ Makefile.am 2001/11/26 01:06:38 1.28 @@ -32,6 +32,7 @@ efsd_main.h efsd_main.c \ efsd_macros.h \ efsd_meta.c efsd_meta.h \ + efsd_meta_monitor.c efsd_meta_monitor.h \ efsd_monitor.h efsd_monitor.c \ efsd_queue.h efsd_queue.c \ efsd_list.h efsd_list.c \ =================================================================== RCS file: /cvsroot/enlightenment/e17/apps/efsd/efsd/efsd.h,v retrieving revision 1.21 retrieving revision 1.22 diff -u -3 -r1.21 -r1.22 --- efsd.h 2001/08/02 22:43:39 1.21 +++ efsd.h 2001/11/26 01:06:38 1.22 @@ -36,28 +36,30 @@ typedef enum efsd_filechange_type { - EFSD_FILE_CHANGED = 1, - EFSD_FILE_DELETED = 2, - EFSD_FILE_START_EXEC = 3, - EFSD_FILE_STOP_EXEC = 4, - EFSD_FILE_CREATED = 5, - EFSD_FILE_MOVED = 6, - EFSD_FILE_ACKNOWLEDGE = 7, - EFSD_FILE_EXISTS = 8, - EFSD_FILE_END_EXISTS = 9 + EFSD_FILE_CHANGED = 1, + EFSD_FILE_DELETED = 2, + EFSD_FILE_START_EXEC = 3, + EFSD_FILE_STOP_EXEC = 4, + EFSD_FILE_CREATED = 5, + EFSD_FILE_MOVED = 6, + EFSD_FILE_ACKNOWLEDGE = 7, + EFSD_FILE_EXISTS = 8, + EFSD_FILE_END_EXISTS = 9, + EFSD_FILE_METADATA_CHANGED = 10 } EfsdFilechangeType; typedef enum efsd_event_type { EFSD_EVENT_FILECHANGE, + EFSD_EVENT_METADATA_CHANGE, EFSD_EVENT_REPLY } EfsdEventType; typedef enum efsd_command_type { - EFSD_CMD_REMOVE, + EFSD_CMD_REMOVE, EFSD_CMD_MOVE, EFSD_CMD_COPY, EFSD_CMD_SYMLINK, @@ -68,8 +70,10 @@ EFSD_CMD_GETMETA, EFSD_CMD_STARTMON_FILE, EFSD_CMD_STARTMON_DIR, + EFSD_CMD_STARTMON_META, EFSD_CMD_STOPMON_FILE, EFSD_CMD_STOPMON_DIR, + EFSD_CMD_STOPMON_META, EFSD_CMD_STAT, EFSD_CMD_LSTAT, EFSD_CMD_READLINK, @@ -206,6 +210,21 @@ EfsdFileChangeEvent; +/* Metadata change event. + */ +typedef struct efsd_metachange_event +{ + EfsdEventType type; + EfsdCmdId id; + char *key; + char *file; + EfsdDatatype datatype; + int data_len; + void *data; +} +EfsdMetadataChangeEvent; + + /* General reply to commands, contains entire command as well */ @@ -230,9 +249,10 @@ /* General event structure */ typedef union efsd_event { - EfsdEventType type; - EfsdFileChangeEvent efsd_filechange_event; - EfsdReplyEvent efsd_reply_event; + EfsdEventType type; + EfsdFileChangeEvent efsd_filechange_event; + EfsdMetadataChangeEvent efsd_metachange_event; + EfsdReplyEvent efsd_reply_event; } EfsdEvent; =================================================================== RCS file: /cvsroot/enlightenment/e17/apps/efsd/efsd/efsd_commands.c,v retrieving revision 1.12 retrieving revision 1.13 diff -u -3 -r1.12 -r1.13 --- efsd_commands.c 2001/11/16 16:44:15 1.12 +++ efsd_commands.c 2001/11/26 01:06:38 1.13 @@ -48,10 +48,12 @@ #include <efsd_filetype.h> #include <efsd_main.h> #include <efsd_meta.h> +#include <efsd_meta_monitor.h> #include <efsd_misc.h> #include <efsd_event_queue.h> #include <efsd_statcache.h> #include <efsd_types.h> +#include <efsd_meta_monitor.h> static void @@ -378,6 +380,36 @@ D_ENTER; if (efsd_monitor_stop(cmd, client, dir_mode) < 0) + { + errno_check(__LINE__, __FUNCTION__); + D_RETURN_(send_reply(cmd, errno, 0, NULL, client)); + } + + D_RETURN_(send_reply(cmd, 0, 0, NULL, client)); +} + + +int +efsd_command_start_monitor_metadata(EfsdCommand *cmd, int client) +{ + D_ENTER; + + if (!efsd_meta_monitor_add(cmd, client)) + { + errno_check(__LINE__, __FUNCTION__); + D_RETURN_(send_reply(cmd, errno, 0, NULL, client)); + } + + D_RETURN_(send_reply(cmd, 0, 0, NULL, client)); +} + + +int +efsd_command_stop_monitor_metadata(EfsdCommand *cmd, int client) +{ + D_ENTER; + + if (!efsd_meta_monitor_del(cmd, client)) { errno_check(__LINE__, __FUNCTION__); D_RETURN_(send_reply(cmd, errno, 0, NULL, client)); =================================================================== RCS file: /cvsroot/enlightenment/e17/apps/efsd/efsd/efsd_commands.h,v retrieving revision 1.3 retrieving revision 1.4 diff -u -3 -r1.3 -r1.4 --- efsd_commands.h 2001/07/27 13:09:29 1.3 +++ efsd_commands.h 2001/11/26 01:06:38 1.4 @@ -38,6 +38,8 @@ int efsd_command_listdir(EfsdCommand *cmd, int client); int efsd_command_start_monitor(EfsdCommand *cmd, int client, int dir_mode); int efsd_command_stop_monitor(EfsdCommand *cmd, int client, int dir_mode); +int efsd_command_start_monitor_metadata(EfsdCommand *cmd, int client); +int efsd_command_stop_monitor_metadata(EfsdCommand *cmd, int client); int efsd_command_stat(EfsdCommand *cmd, int client, char use_lstat); int efsd_command_readlink(EfsdCommand *cmd, int client); int efsd_command_get_filetype(EfsdCommand *cmd, int client); =================================================================== RCS file: /cvsroot/enlightenment/e17/apps/efsd/efsd/efsd_filetype.c,v retrieving revision 1.33 retrieving revision 1.34 diff -u -3 -r1.33 -r1.34 --- efsd_filetype.c 2001/11/16 16:44:15 1.33 +++ efsd_filetype.c 2001/11/26 01:06:38 1.34 @@ -60,6 +60,10 @@ #undef DEBUG #endif +#ifdef DEBUG_NEST +#undef DEBUG_NEST +#endif + #include <efsd.h> #include <efsd_debug.h> #include <efsd_lock.h> =================================================================== RCS file: /cvsroot/enlightenment/e17/apps/efsd/efsd/efsd_io.c,v retrieving revision 1.40 retrieving revision 1.41 diff -u -3 -r1.40 -r1.41 --- efsd_io.c 2001/09/30 18:35:07 1.40 +++ efsd_io.c 2001/11/26 01:06:38 1.41 @@ -82,6 +82,7 @@ static int read_set_metadata_cmd(int sockfd, EfsdCommand *cmd); static int read_get_metadata_cmd(int sockfd, EfsdCommand *cmd); static int read_filechange_event(int sockfd, EfsdEvent *ee); +static int read_metadata_change_event(int sockfd, EfsdEvent *ee); static int read_reply_event(int sockfd, EfsdEvent *ee); static int read_getmeta_op(int sockfd, EfsdOption *eo); @@ -91,6 +92,7 @@ static void fill_get_metadata_cmd(EfsdIOV *iov, EfsdCommand *ec); static void fill_close_cmd(EfsdIOV *iov, EfsdCommand *ec); static void fill_filechange_event(EfsdIOV *iov, EfsdEvent *ee); +static void fill_metadata_change_event(EfsdIOV *iov, EfsdEvent *ee); static void fill_reply_event(EfsdIOV *iov, EfsdEvent *ee); static void fill_event(EfsdIOV *iov, EfsdEvent *ee); static void fill_command(EfsdIOV *iov, EfsdCommand *ec); @@ -109,7 +111,10 @@ D_ENTER; if (sockfd < 0) - D_RETURN_(-1); + { + D("Socket < 0 ???\n"); + D_RETURN_(-1); + } tv.tv_sec = 1; tv.tv_usec = 0; @@ -387,6 +392,53 @@ static int +read_metadata_change_event(int sockfd, EfsdEvent *ee) +{ + int count, count2; + + D_ENTER; + + if ((count = read_int(sockfd, &(ee->efsd_metachange_event.id))) < 0) + D_RETURN_(-1); + count2 = count; + + if ((count = read_string(sockfd, &(ee->efsd_metachange_event.key))) < 0) + D_RETURN_(-1); + count2 += count; + + if ((count = read_string(sockfd, &(ee->efsd_metachange_event.file))) < 0) + D_RETURN_(-1); + count2 += count; + + if ((count = read_int(sockfd, (int*)&(ee->efsd_metachange_event.datatype))) < 0) + D_RETURN_(-1); + count2 += count; + + if ((count = read_int(sockfd, (int*)&(ee->efsd_metachange_event.data_len))) < 0) + D_RETURN_(-1); + count2 += count; + + if (ee->efsd_metachange_event.data_len > 0) + { + ee->efsd_metachange_event.data = + malloc(ee->efsd_metachange_event.data_len); + + if ((count = read_data(sockfd, (ee->efsd_metachange_event.data), + ee->efsd_metachange_event.data_len)) < 0) + D_RETURN_(-1); + count2 += count; + } + else + { + ee->efsd_metachange_event.data_len = 0; + ee->efsd_metachange_event.data = NULL; + } + + D_RETURN_(count2); +} + + +static int read_reply_event(int sockfd, EfsdEvent *ee) { int count = 0, count2; @@ -614,6 +666,46 @@ } +static void +fill_metadata_change_event(EfsdIOV *iov, EfsdEvent *ee) +{ + D_ENTER; + + iov->dat[iov->d] = strlen(ee->efsd_metachange_event.key) + 1; + iov->dat[iov->d+1] = strlen(ee->efsd_metachange_event.file) + 1; + + iov->vec[iov->v].iov_base = &ee->type; + iov->vec[iov->v].iov_len = sizeof(EfsdEventType); + + iov->vec[++iov->v].iov_base = &ee->efsd_metachange_event.id; + iov->vec[iov->v].iov_len = sizeof(EfsdCmdId); + + iov->vec[++iov->v].iov_base = &(iov->dat[iov->d]); + iov->vec[iov->v].iov_len = sizeof(int); + iov->vec[++iov->v].iov_base = ee->efsd_metachange_event.key; + iov->vec[iov->v].iov_len = iov->dat[iov->d]; + + iov->vec[++iov->v].iov_base = &(iov->dat[iov->d+1]); + iov->vec[iov->v].iov_len = sizeof(int); + iov->vec[++iov->v].iov_base = ee->efsd_metachange_event.file; + iov->vec[iov->v].iov_len = iov->dat[iov->d+1]; + + iov->vec[++iov->v].iov_base = &ee->efsd_metachange_event.datatype; + iov->vec[iov->v].iov_len = sizeof(int); + + iov->vec[++iov->v].iov_base = &ee->efsd_metachange_event.data_len; + iov->vec[iov->v].iov_len = sizeof(int); + + iov->vec[++iov->v].iov_base = ee->efsd_metachange_event.data; + iov->vec[iov->v].iov_len = ee->efsd_metachange_event.data_len; + + iov->d += 2; + iov->v++; + + D_RETURN; +} + + static void fill_reply_event(EfsdIOV *iov, EfsdEvent *ee) { @@ -625,7 +717,7 @@ fill_command(iov, &ee->efsd_reply_event.command); - iov->vec[iov->v].iov_base = &ee->efsd_reply_event.errorcode; + iov->vec[iov->v].iov_base = &ee->efsd_reply_event.errorcode; iov->vec[iov->v].iov_len = sizeof(int); iov->vec[++iov->v].iov_base = &ee->efsd_reply_event.data_len; iov->vec[iov->v].iov_len = sizeof(int); @@ -649,6 +741,9 @@ case EFSD_EVENT_FILECHANGE: fill_filechange_event(iov, ee); break; + case EFSD_EVENT_METADATA_CHANGE: + fill_metadata_change_event(iov, ee); + break; case EFSD_EVENT_REPLY: fill_reply_event(iov, ee); break; @@ -672,8 +767,10 @@ case EFSD_CMD_LISTDIR: case EFSD_CMD_STARTMON_FILE: case EFSD_CMD_STARTMON_DIR: + case EFSD_CMD_STARTMON_META: case EFSD_CMD_STOPMON_FILE: case EFSD_CMD_STOPMON_DIR: + case EFSD_CMD_STOPMON_META: case EFSD_CMD_STAT: case EFSD_CMD_LSTAT: case EFSD_CMD_READLINK: @@ -795,8 +892,10 @@ case EFSD_CMD_LISTDIR: case EFSD_CMD_STARTMON_FILE: case EFSD_CMD_STARTMON_DIR: + case EFSD_CMD_STARTMON_META: case EFSD_CMD_STOPMON_FILE: case EFSD_CMD_STOPMON_DIR: + case EFSD_CMD_STOPMON_META: case EFSD_CMD_STAT: case EFSD_CMD_LSTAT: case EFSD_CMD_READLINK: @@ -874,6 +973,9 @@ { case EFSD_EVENT_FILECHANGE: result = read_filechange_event(sockfd, ee); + break; + case EFSD_EVENT_METADATA_CHANGE: + result = read_metadata_change_event(sockfd, ee); break; case EFSD_EVENT_REPLY: result = read_reply_event(sockfd, ee); =================================================================== RCS file: /cvsroot/enlightenment/e17/apps/efsd/efsd/efsd_list.c,v retrieving revision 1.6 retrieving revision 1.7 diff -u -3 -r1.6 -r1.7 --- efsd_list.c 2001/09/30 18:35:07 1.6 +++ efsd_list.c 2001/11/26 01:06:38 1.7 @@ -29,6 +29,14 @@ #include <stdio.h> #include <stdlib.h> +#ifdef DEBUG +#undef DEBUG +#endif + +#ifdef DEBUG_NEST +#undef DEBUG_NEST +#endif + #include <efsd_macros.h> #include <efsd_debug.h> #include <efsd_misc.h> =================================================================== RCS file: /cvsroot/enlightenment/e17/apps/efsd/efsd/efsd_main.c,v retrieving revision 1.50 retrieving revision 1.51 diff -u -3 -r1.50 -r1.51 --- efsd_main.c 2001/11/16 16:44:15 1.50 +++ efsd_main.c 2001/11/26 01:06:38 1.51 @@ -58,6 +58,7 @@ #include <efsd_macros.h> #include <efsd_main.h> #include <efsd_meta.h> +#include <efsd_meta_monitor.h> #include <efsd_misc.h> #include <efsd_event_queue.h> #include <efsd_types.h> @@ -257,6 +258,10 @@ D("Handling STARTMON_DIR\n"); efsd_command_start_monitor(command, client, TRUE); break; + case EFSD_CMD_STARTMON_META: + D("Handling STARTMON_META\n"); + efsd_command_start_monitor_metadata(command, client); + break; case EFSD_CMD_STOPMON_FILE: D("Handling STOPMON_FILE\n"); efsd_command_stop_monitor(command, client, FALSE); @@ -265,6 +270,10 @@ D("Handling STOPMON_DIR\n"); efsd_command_stop_monitor(command, client, TRUE); break; + case EFSD_CMD_STOPMON_META: + D("Handling STOPMON_META\n"); + efsd_command_stop_monitor_metadata(command, client); + break; case EFSD_CMD_STAT: D("Handling STAT on %s\n", command->efsd_file_cmd.files[0]); efsd_command_stat(command, client, FALSE); @@ -659,7 +668,8 @@ fd_set *fdwset_ptr = NULL; char have_fam_thread = FALSE; struct timeval tv; - + int rebuild_fdset = FALSE; + D_ENTER; ev_q = efsd_queue_new(); @@ -711,7 +721,8 @@ for ( ; ; ) { - can_accept = 0; + rebuild_fdset = FALSE; + can_accept = FALSE; FD_ZERO(&fdrset); FD_ZERO(&fdwset); fdwset_ptr = NULL; @@ -736,7 +747,7 @@ fdsize = clientfd[i]; } else - can_accept = 1; + can_accept = TRUE; } /* listen for new connections */ @@ -774,13 +785,21 @@ } else { - fprintf(stderr, __FUNCTION__ ": select error -- exiting.\n"); - exit(-1); + D("Select error: %s.\n", strerror(errno)); + + /* FIXME -- if we get a bad descriptor here, we need to close + that connection properly and rebuild the fdset. */ + + rebuild_fdset = TRUE; } tv.tv_sec = 1; tv.tv_usec = 0; } + /* If something went wrong with the select, start over. */ + if (rebuild_fdset) + continue; + /* if we timed out - ie 0 fd's available */ if (n == 0) efsd_meta_idle(); @@ -816,7 +835,6 @@ } else { - efsd_main_close_connection(i); efsd_cmd_free(ecmd); } } @@ -1001,7 +1019,7 @@ { D("Cleaning up client %i, fd %i\n", i, clientfd[i]); close(clientfd[i]); - clientfd[i] = 0; + clientfd[i] = -1; } } @@ -1184,17 +1202,18 @@ efsd_main_close_connection(int client) { D_ENTER; - D("Closing connection %i\n", client); if (clientfd[client] < 0) { - D("Connection already closed ???\n"); D_RETURN_(-1); } + D("Closing connection %i\n", client); efsd_monitor_cleanup_client(client); + efsd_meta_monitor_cleanup_client(client); close(clientfd[client]); clientfd[client] = -1; + D_RETURN_(0); } @@ -1210,6 +1229,7 @@ efsd_monitor_init(); efsd_stat_init(); efsd_meta_init(); + efsd_meta_monitor_init(); efsd_filetype_init(); main_initialize(argv[0]); =================================================================== RCS file: /cvsroot/enlightenment/e17/apps/efsd/efsd/efsd_meta.c,v retrieving revision 1.14 retrieving revision 1.15 diff -u -3 -r1.14 -r1.15 --- efsd_meta.c 2001/11/16 16:44:15 1.14 +++ efsd_meta.c 2001/11/26 01:06:38 1.15 @@ -40,19 +40,18 @@ #include <efsd_debug.h> #include <efsd_macros.h> #include <efsd_misc.h> +#include <efsd_hash.h> +#include <efsd_monitor.h> #include <efsd_statcache.h> #include <efsd_lock.h> -#include <efsd_meta.h> #include <efsd_fs.h> - - +#include <efsd_meta_monitor.h> +#include <efsd_meta.h> +/* This lock manages concurrent access to metadata dbs */ EfsdLock *meta_lock; static char * meta_get_user_metadata_filename(void); -static int meta_db_get_file(char *filename, - char *dbfile, int db_len, - char *key, int key_len, int create); static int meta_db_set_data(EfsdSetMetadataCmd *esmc, char *key_base, char *dbfile); @@ -96,136 +95,6 @@ D_RETURN_(s); } -static int -meta_db_get_file(char *filename, - char *dbfile, int db_len, - char *key, int key_len, int create) -{ - char s[MAXPATHLEN], filename_copy[MAXPATHLEN]; - char *path, *file; - int use_home_dir = FALSE; - struct stat st; - - D_ENTER; - - if (!filename || filename[0] != '/') - { - D("Invalid filename\n"); - errno = ENOENT; - D_RETURN_(FALSE); - } - - snprintf(filename_copy, MAXPATHLEN, "%s", filename); - path = filename_copy; - - file = strrchr(filename_copy, '/'); - if (!file) - { - /* Something's wrong -- this is supposed to be - a chanonical path ... - */ - D("Couldn't find '/' in filename '%s'\n", filename); - errno = EINVAL; - D_RETURN_(FALSE); - } - - /* terminate the string where the path ends, - cutting of the filename... - */ - *file = '\0'; - file++; - - /* file is now the filename only, path is now the path only. */ - - if (*path == '\0') - { - path = "/"; - snprintf(s, MAXPATHLEN, "/%s", EFSD_META_DIR_NAME); - } - else - { - snprintf(s, MAXPATHLEN, "%s/%s", path, EFSD_META_DIR_NAME); - } - - /* s is now the metadata directory for the given file, out - in the filesystem. Check if the directory exists - and is accessible. - */ - - if (efsd_misc_file_exists(s)) - { - if (efsd_misc_file_writeable(s) && - efsd_misc_file_execable(s)) - /* Can access and manipulate --> use it. */ - use_home_dir = FALSE; - else - /* No access --> need to put metadata in home dir */ - use_home_dir = TRUE; - } - else - { - if (efsd_misc_file_writeable(path) && - efsd_misc_file_execable(path)) - { - if (!efsd_stat(path, &st)) - { - use_home_dir = TRUE; - } - else - { - if (!create) - { - D("Not existant metadata dir %s, no create -- returning false.\n", s); - D_RETURN_(FALSE); - } - - /* We're told to create the metadata directory, so try it ... */ - umask(000); - - if (mkdir(s, st.st_mode) < 0) - use_home_dir = TRUE; - else - use_home_dir = FALSE; - - umask(077); - } - } - else - { - use_home_dir = TRUE; - } - } - - /* We use different keys to access metadata, depending on - whether we're in the global directory in the user's home - or locally out in the filesystem. When we're in the home - dir, we use the full path and filename. When we're local, - we just use the file name, without the path. - - By doing this we can rename an entire directory - branch without having to adjust all the metadata - file names in the subtree. - */ - - if (use_home_dir) - { - snprintf(dbfile, db_len, "%s/%s", - efsd_misc_get_user_dir(), EFSD_META_FILE_NAME); - - snprintf(key, key_len, "/meta%s", filename); - } - else - { - snprintf(dbfile, db_len, "%s/%s", - s, meta_get_user_metadata_filename()); - - snprintf(key, key_len, "/meta/%s", file); - } - D("Returning success.\n"); - - D_RETURN_(TRUE); -} - int efsd_meta_copy_data(char *from_file, char *to_file) @@ -245,16 +114,16 @@ D("Copying metadata from file %s to %s\n", from_file, to_file); - if (!meta_db_get_file(from_file, - from_db_file, MAXPATHLEN, - from_key, MAXPATHLEN, - FALSE)) + if (!efsd_meta_get_file_info(from_file, + from_db_file, MAXPATHLEN, + from_key, MAXPATHLEN, + FALSE)) D_RETURN_(FALSE); - if (!meta_db_get_file(to_file, - to_db_file, MAXPATHLEN, - to_key, MAXPATHLEN, - TRUE)) + if (!efsd_meta_get_file_info(to_file, + to_db_file, MAXPATHLEN, + to_key, MAXPATHLEN, + TRUE)) D_RETURN_(FALSE); D("From %s %s to %s %s\n", from_db_file, from_key, to_db_file, to_key); @@ -342,7 +211,7 @@ D("Removing metadata of file %s\n", file); - if (!meta_db_get_file(file, + if (!efsd_meta_get_file_info(file, db_file, MAXPATHLEN, key, MAXPATHLEN, FALSE)) @@ -392,7 +261,11 @@ D_RETURN_(0); } + efsd_meta_monitor_notify(esmc->file, esmc->key, esmc->datatype, + esmc->data_len, esmc->data); + snprintf(key, MAXPATHLEN, "%s%s", key_base, esmc->key); + switch (esmc->datatype) { @@ -553,8 +426,8 @@ esmc = &(ec->efsd_set_metadata_cmd); efsd_misc_remove_trailing_slashes(esmc->file); - meta_db_get_file(esmc->file, db_file, MAXPATHLEN, - key_base, MAXPATHLEN, TRUE /* create */); + efsd_meta_get_file_info(esmc->file, db_file, MAXPATHLEN, + key_base, MAXPATHLEN, TRUE /* create */); D("Writing to %s for %s\n", db_file, esmc->file); @@ -580,8 +453,8 @@ egmc = &(ec->efsd_get_metadata_cmd); efsd_misc_remove_trailing_slashes(egmc->file); - if (meta_db_get_file(egmc->file, db_file, MAXPATHLEN, - key_base, MAXPATHLEN, FALSE) == FALSE) + if (efsd_meta_get_file_info(egmc->file, db_file, MAXPATHLEN, + key_base, MAXPATHLEN, FALSE) == FALSE) D_RETURN_(NULL); success = meta_db_get_data(egmc, key_base, db_file, data_len); @@ -632,3 +505,140 @@ D_RETURN; } + + +int +efsd_meta_get_file_info(char *filename, + char *dbfile, int db_len, + char *key, int key_len, int create) +{ + char s[MAXPATHLEN], filename_copy[MAXPATHLEN]; + char *path, *file; + int use_home_dir = FALSE; + struct stat st; + + D_ENTER; + + if (!filename || filename[0] != '/') + { + D("Invalid filename\n"); + errno = ENOENT; + D_RETURN_(FALSE); + } + + snprintf(filename_copy, MAXPATHLEN, "%s", filename); + path = filename_copy; + + file = strrchr(filename_copy, '/'); + if (!file) + { + /* Something's wrong -- this is supposed to be + a chanonical path ... + */ + D("Couldn't find '/' in filename '%s'\n", filename); + errno = EINVAL; + D_RETURN_(FALSE); + } + + /* terminate the string where the path ends, + cutting of the filename... + */ + *file = '\0'; + file++; + + /* file is now the filename only, path is now the path only. */ + + if (*path == '\0') + { + path = "/"; + snprintf(s, MAXPATHLEN, "/%s", EFSD_META_DIR_NAME); + } + else + { + snprintf(s, MAXPATHLEN, "%s/%s", path, EFSD_META_DIR_NAME); + } + + /* s is now the metadata directory for the given file, out + in the filesystem. Check if the directory exists + and is accessible. + */ + + if (efsd_misc_file_exists(s)) + { + if (efsd_misc_file_readable(s) && + efsd_misc_file_execable(s)) + /* Can access and manipulate --> use it. */ + use_home_dir = FALSE; + else + /* No access --> need to put metadata in home dir */ + use_home_dir = TRUE; + } + else + { + if (efsd_misc_file_readable(path) && + efsd_misc_file_execable(path)) + { + if (!efsd_stat(path, &st)) + { + use_home_dir = TRUE; + } + else + { + if (!create) + { + D("Not existant metadata dir %s, no create -- returning false.\n", s); + D_RETURN_(FALSE); + } + + /* We're told to create the metadata directory, so try it ... */ + umask(000); + + if (mkdir(s, st.st_mode) < 0) + use_home_dir = TRUE; + else + use_home_dir = FALSE; + + umask(077); + } + } + else + { + use_home_dir = TRUE; + } + } + + /* We use different keys to access metadata, depending on + whether we're in the global directory in the user's home + or locally out in the filesystem. When we're in the home + dir, we use the full path and filename. When we're local, + we just use the file name, without the path. + + By doing this we can rename an entire directory + branch without having to adjust all the metadata + file names in the subtree. + */ + + if (use_home_dir) + { + if (dbfile) + snprintf(dbfile, db_len, "%s/%s", + efsd_misc_get_user_dir(), EFSD_META_FILE_NAME); + + if (key) + snprintf(key, key_len, "/meta%s", filename); + } + else + { + if (dbfile) + snprintf(dbfile, db_len, "%s/%s", + s, meta_get_user_metadata_filename()); + + if (key) + snprintf(key, key_len, "/meta/%s", file); + } + D("Returning success.\n"); + + D_RETURN_(TRUE); +} + + =================================================================== RCS file: /cvsroot/enlightenment/e17/apps/efsd/efsd/efsd_meta.h,v retrieving revision 1.6 retrieving revision 1.7 diff -u -3 -r1.6 -r1.7 --- efsd_meta.h 2001/11/16 16:44:15 1.6 +++ efsd_meta.h 2001/11/26 01:06:38 1.7 @@ -96,4 +96,26 @@ */ void efsd_meta_idle(void); + +/** + * efsd_meta_get_file_info - Returns info about metadata for a file + * @filename: The full path name of the file. + * @dbfile: Result pointer to location of db file for @filename. + * @db_len: Length of string to write result into. + * @key: Result pointer to metadata key prefix for @filename. + * @key_len: Length of string to write result into. + * @create: Flag which causes the metadata directory to be created if it doesn't exist yet. + * + * This is a helper function that looks at the given + * filename and returns the location of the metadata + * db file and the key prefix that depends on the location + * of the file (it can be just the file name or the full + * path). + * + * Returns TRUE if operation was successfull, FALSE otherwise. + */ +int efsd_meta_get_file_info(char *filename, + char *dbfile, int db_len, + char *key, int key_len, int create); + #endif =================================================================== RCS file: /cvsroot/enlightenment/e17/apps/efsd/efsd/efsd_misc.c,v retrieving revision 1.34 retrieving revision 1.35 diff -u -3 -r1.34 -r1.35 --- efsd_misc.c 2001/11/16 16:44:15 1.34 +++ efsd_misc.c 2001/11/26 01:06:38 1.35 @@ -34,6 +34,7 @@ #include <string.h> #include <stdlib.h> #include <errno.h> +#include <pwd.h> #ifdef __EMX__ #include <stdlib.h> @@ -119,6 +120,39 @@ } +int +efsd_misc_file_readable(char *filename) +{ + struct stat st; + + D_ENTER; + + if (!filename) + D_RETURN_(FALSE); + + if (!efsd_stat(filename, &st)) + D_RETURN_(FALSE); + + if (st.st_uid == geteuid()) + { + if (st.st_mode & S_IRUSR) + D_RETURN_(TRUE); + } + else if (st.st_gid == getgid()) + { + if (st.st_mode & S_IRGRP) + D_RETURN_(TRUE); + } + else + { + if (st.st_mode & S_IROTH) + D_RETURN_(TRUE); + } + + D_RETURN_(FALSE); +} + + int efsd_misc_file_execable(char *filename) { @@ -460,27 +494,25 @@ void efsd_misc_create_efsd_dir(void) { - char *dir = NULL; - char s[MAXPATHLEN]; + struct passwd *pw = NULL; + char dir[MAXPATHLEN]; + char s[MAXPATHLEN]; D_ENTER; - - dir = getenv("HOME"); - - /* I'm not using getenv("TMPDIR") -- - * I don't see TMPDIR on Linux, FreeBSD - * or Solaris here... - */ - if (!dir) - dir = "/tmp"; - - snprintf(s, sizeof(s), "%s/.e", dir); + if ( (pw = getpwuid(geteuid()))) + { + snprintf(dir, MAXPATHLEN, "%s/.e", pw->pw_dir); + } + else + { + snprintf(dir, MAXPATHLEN, "/tmp/.efsd_%u", geteuid()); + } - if (!efsd_misc_file_is_dir(s)) - efsd_misc_mkdir(s); + if (!efsd_misc_file_is_dir(dir)) + efsd_misc_mkdir(dir); - snprintf(s, sizeof(s), "%s/.e/efsd", dir); + snprintf(s, sizeof(s), "%s/efsd", dir); if (!efsd_misc_file_is_dir(s)) efsd_misc_mkdir(s); =================================================================== RCS file: /cvsroot/enlightenment/e17/apps/efsd/efsd/efsd_misc.h,v retrieving revision 1.22 retrieving revision 1.23 diff -u -3 -r1.22 -r1.23 --- efsd_misc.h 2001/11/16 16:44:15 1.22 +++ efsd_misc.h 2001/11/26 01:06:38 1.23 @@ -25,15 +25,18 @@ #ifndef __efsd_misc_h #define __efsd_misc_h + +/* These do the obvious ... */ int efsd_misc_file_exists(char *filename); int efsd_misc_file_is_dir(char *filename); +int efsd_misc_file_readable(char *filename); int efsd_misc_file_writeable(char *filename); int efsd_misc_file_execable(char *filename); int efsd_misc_file_is_dotfile(char *filename); /* Checks if file paths are identical after making them chanonic -- returns < 0 on error, FALSE - if files differ, TRUE otherwise. + if files differ, TRUE otherwise. Not an inode check. */ int efsd_misc_files_identical(char *file1, char *file2); @@ -43,8 +46,14 @@ */ int efsd_misc_remove(char *filename); +/* Wrapper to rename() that updates the stat cache + and handles metadata properly. Returns TRUE on + success, FALSE otherwise. +*/ int efsd_misc_rename(char *file1, char *file2); +/* Simple mkdir wrapper. + */ int efsd_misc_mkdir(char *filename); void efsd_misc_remove_trailing_slashes(char *path); int efsd_misc_is_absolute_path(char *path); =================================================================== RCS file: /cvsroot/enlightenment/e17/apps/efsd/efsd/efsd_monitor.c,v retrieving revision 1.20 retrieving revision 1.21 diff -u -3 -r1.20 -r1.21 --- efsd_monitor.c 2001/11/16 16:44:15 1.20 +++ efsd_monitor.c 2001/11/26 01:06:38 1.21 @@ -67,10 +67,6 @@ static void monitor_free(EfsdMonitor *m); -static EfsdMonitorRequest *monitor_request_new(int client, EfsdFileCmd *cmd); - -static void monitor_request_free(EfsdMonitorRequest *emr); - /* Increment use count for file monitor, or start new monitor if file is not monitored yet. */ @@ -191,7 +187,7 @@ m->clients = NULL; m->files = efsd_dca_new(); - emr = monitor_request_new(client, &com->efsd_file_cmd); + emr = efsd_monitor_request_new(client, &com->efsd_file_cmd); m->clients = efsd_list_prepend(m->clients, emr); @@ -237,7 +233,7 @@ FREE(m->filename); FREE(m->fam_req); - efsd_list_free(m->clients, (EfsdFunc)monitor_request_free); + efsd_list_free(m->clients, (EfsdFunc)efsd_monitor_request_free); efsd_dca_free(m->files); #if USE_THREADS @@ -250,54 +246,6 @@ } -static EfsdMonitorRequest * -monitor_request_new(int client, EfsdFileCmd *cmd) -{ - EfsdMonitorRequest *emr; - - D_ENTER; - - emr = NEW(EfsdMonitorRequest); - memset(emr, 0, sizeof(EfsdMonitorRequest)); - - emr->client = client; - emr->id = cmd->id; - - /* Unhook (not free) the options from the command, so - that they don't get freed in the normal command - cleanup. They will get cleaned up when we see the - acknowledge event and the EfsdMonitorRequest is freed. - */ - - if (cmd->num_options > 0) - { - emr->num_options = cmd->num_options; - emr->options = cmd->options; - cmd->num_options = 0; - cmd->options = NULL; - } - - D_RETURN_(emr); -} - - -static void -monitor_request_free(EfsdMonitorRequest *emr) -{ - int i; - - D_ENTER; - - for (i = 0; i < emr->num_options; i++) - efsd_option_cleanup(&emr->options[i]); - - FREE(emr->options); - FREE(emr); - - D_RETURN; -} - - static void monitor_hash_item_free(EfsdHashItem *it) { @@ -345,6 +293,54 @@ } +EfsdMonitorRequest * +efsd_monitor_request_new(int client, EfsdFileCmd *cmd) +{ + EfsdMonitorRequest *emr; + + D_ENTER; + + emr = NEW(EfsdMonitorRequest); + memset(emr, 0, sizeof(EfsdMonitorRequest)); + + emr->client = client; + emr->id = cmd->id; + + /* Unhook (not free) the options from the command, so + that they don't get freed in the normal command + cleanup. They will get cleaned up when we see the + acknowledge event and the EfsdMonitorRequest is freed. + */ + + if (cmd->num_options > 0) + { + emr->num_options = cmd->num_options; + emr->options = cmd->options; + cmd->num_options = 0; + cmd->options = NULL; + } + + D_RETURN_(emr); +} + + +void +efsd_monitor_request_free(EfsdMonitorRequest *emr) +{ + int i; + + D_ENTER; + + for (i = 0; i < emr->num_options; i++) + efsd_option_cleanup(&emr->options[i]); + + FREE(emr->options); + FREE(emr); + + D_RETURN; +} + + void efsd_monitor_send_filechange_events(EfsdMonitor *m, EfsdMonitorRequest *emr) { @@ -453,7 +449,7 @@ m->filename, m->internal_use_count, m->client_use_count); } - emr = monitor_request_new(client, &com->efsd_file_cmd); + emr = efsd_monitor_request_new(client, &com->efsd_file_cmd); m->clients = efsd_list_prepend(m->clients, emr); UNLOCK(&m->use_count_mutex); @@ -575,7 +571,7 @@ if (!m->is_receiving_exist_events) { m->clients = efsd_list_remove(m->clients, l2, - (EfsdFunc)monitor_request_free); + (EfsdFunc)efsd_monitor_request_free); } else { @@ -592,7 +588,7 @@ if (!m->is_receiving_exist_events) { m->clients = efsd_list_remove(m->clients, l2, - (EfsdFunc)monitor_request_free); + (EfsdFunc)efsd_monitor_request_free); } else { @@ -830,7 +826,7 @@ } -int +void efsd_monitor_cleanup_client(int client) { EfsdList *l; @@ -862,7 +858,7 @@ client, m->filename, m->internal_use_count, m->client_use_count); D("Removing client %i from monitor for %s\n", client, m->filename); - m->clients = efsd_list_remove(m->clients, l, (EfsdFunc)monitor_request_free); + m->clients = efsd_list_remove(m->clients, l, (EfsdFunc)efsd_monitor_request_free); if (m->client_use_count == 0 && m->internal_use_count == 0) { @@ -877,7 +873,7 @@ efsd_lock_release_read_access(monitors_lock); efsd_hash_it_free(it); - D_RETURN_(FALSE); + D_RETURN; } @@ -900,7 +896,7 @@ { LOCK(&m->use_count_mutex); m->clients = efsd_list_remove(m->clients, l, - (EfsdFunc)monitor_request_free); + (EfsdFunc)efsd_monitor_request_free); UNLOCK(&m->use_count_mutex); } } =================================================================== RCS file: /cvsroot/enlightenment/e17/apps/efsd/efsd/efsd_monitor.h,v retrieving revision 1.10 retrieving revision 1.11 diff -u -3 -r1.10 -r1.11 --- efsd_monitor.h 2001/08/03 08:36:23 1.10 +++ efsd_monitor.h 2001/11/26 01:06:38 1.11 @@ -72,7 +72,7 @@ /* Which clients monitor this file, and with what command id. - list<EfsdFamRequest*>. + list<EfsdMonitorRequest*>. */ EfsdList *clients; @@ -118,6 +118,10 @@ void efsd_monitor_init(void); void efsd_monitor_cleanup(void); +EfsdMonitorRequest *efsd_monitor_request_new(int client, EfsdFileCmd *cmd); +void efsd_monitor_request_free(EfsdMonitorRequest *emr); + + /* This one frees the monitor and removes it from the list of registered monitors. */ @@ -141,7 +145,7 @@ /* Check for all monitors if they are requested by CLIENT and in that case release those requests. */ -int efsd_monitor_cleanup_client(int client); +void efsd_monitor_cleanup_client(int client); /* Checks all monitoring requests for a particular monitor and removes those requests that are no longer valid. =================================================================== RCS file: /cvsroot/enlightenment/e17/apps/efsd/efsd/efsd_stack.c,v retrieving revision 1.2 retrieving revision 1.3 diff -u -3 -r1.2 -r1.3 --- efsd_stack.c 2001/08/23 14:25:50 1.2 +++ efsd_stack.c 2001/11/26 01:06:38 1.3 @@ -29,6 +29,14 @@ #include <stdio.h> #include <stdlib.h> +#ifdef DEBUG +#undef DEBUG +#endif + +#ifdef DEBUG_NEST +#undef DEBUG_NEST +#endif + #include <efsd_macros.h> #include <efsd_debug.h> #include <efsd_misc.h> =================================================================== RCS file: /cvsroot/enlightenment/e17/apps/efsd/efsd/efsd_types.c,v retrieving revision 1.18 retrieving revision 1.19 diff -u -3 -r1.18 -r1.19 --- efsd_types.c 2001/08/01 08:53:04 1.18 +++ efsd_types.c 2001/11/26 01:06:38 1.19 @@ -74,8 +74,10 @@ case EFSD_CMD_CHMOD: case EFSD_CMD_STARTMON_FILE: case EFSD_CMD_STARTMON_DIR: + case EFSD_CMD_STARTMON_META: case EFSD_CMD_STOPMON_FILE: case EFSD_CMD_STOPMON_DIR: + case EFSD_CMD_STOPMON_META: case EFSD_CMD_LISTDIR: case EFSD_CMD_STAT: case EFSD_CMD_LSTAT: @@ -148,11 +150,24 @@ switch (ee_src->type) { case EFSD_EVENT_FILECHANGE: - ee_dst->efsd_filechange_event.file = strdup(ee_src->efsd_filechange_event.file); + ee_dst->efsd_filechange_event.file = + strdup(ee_src->efsd_filechange_event.file); break; + case EFSD_EVENT_METADATA_CHANGE: + ee_dst->efsd_metachange_event.file = + strdup(ee_src->efsd_metachange_event.file); + + ee_dst->efsd_metachange_event.key = + strdup(ee_src->efsd_metachange_event.key); + + d = malloc(sizeof(char) * ee_src->efsd_metachange_event.data_len); + memcpy(d, ee_src->efsd_metachange_event.data, ee_src->efsd_metachange_event.data_len); + ee_dst->efsd_metachange_event.data = d; + break; case EFSD_EVENT_REPLY: efsd_cmd_duplicate(&(ee_src->efsd_reply_event.command), &(ee_dst->efsd_reply_event.command)); + d = malloc(sizeof(char) * ee_src->efsd_reply_event.data_len); memcpy(d, ee_src->efsd_reply_event.data, ee_src->efsd_reply_event.data_len); ee_dst->efsd_reply_event.data = d; @@ -194,13 +209,15 @@ case EFSD_CMD_MAKEDIR: case EFSD_CMD_STOPMON_FILE: case EFSD_CMD_STOPMON_DIR: + case EFSD_CMD_STOPMON_META: + case EFSD_CMD_STARTMON_DIR: + case EFSD_CMD_STARTMON_FILE: + case EFSD_CMD_STARTMON_META: case EFSD_CMD_STAT: case EFSD_CMD_LSTAT: case EFSD_CMD_GETFILETYPE: case EFSD_CMD_READLINK: case EFSD_CMD_LISTDIR: - case EFSD_CMD_STARTMON_DIR: - case EFSD_CMD_STARTMON_FILE: case EFSD_CMD_COPY: case EFSD_CMD_MOVE: case EFSD_CMD_SYMLINK: @@ -259,8 +276,13 @@ switch (ev->type) { case EFSD_EVENT_REPLY: - FREE(ev->efsd_reply_event.data); + FREE(ev->efsd_reply_event.data); efsd_cmd_cleanup(&ev->efsd_reply_event.command); + break; + case EFSD_EVENT_METADATA_CHANGE: + FREE(ev->efsd_metachange_event.data); + FREE(ev->efsd_metachange_event.key); + FREE(ev->efsd_metachange_event.file); break; case EFSD_EVENT_FILECHANGE: FREE(ev->efsd_filechange_event.file); =================================================================== RCS file: /cvsroot/enlightenment/e17/apps/efsd/efsd/libefsd.c,v retrieving revision 1.54 retrieving revision 1.55 diff -u -3 -r1.54 -r1.55 --- libefsd.c 2001/11/16 22:05:36 1.54 +++ libefsd.c 2001/11/26 01:06:38 1.55 @@ -74,21 +74,26 @@ }; -static int send_command(EfsdConnection *ec, EfsdCommand *com); -static EfsdCmdId get_next_id(void); +static char *libefsd_get_full_path(char *file); +static int libefsd_send_command(EfsdConnection *ec, EfsdCommand *com); +static EfsdCmdId libefsd_get_next_id(void); + +static EfsdCmdId libefsd_file_cmd_absolute(EfsdConnection *ec, EfsdCommandType type, + int num_files, char **files, + int num_options, EfsdOption *ops); + +static EfsdCmdId libefsd_file_cmd(EfsdConnection *ec, EfsdCommandType type, + int num_files, char **files, + int num_options, EfsdOption *ops); -static EfsdCmdId file_cmd(EfsdConnection *ec, EfsdCommandType type, - int num_files, char **files, - int num_options, EfsdOption *ops); - -static EfsdCmdId set_metadata_internal(EfsdConnection *ec, char *key, char *filename, - EfsdDatatype datatype, int data_len, void *data); +static EfsdCmdId libefsd_set_metadata_internal(EfsdConnection *ec, char *key, char *filename, + EfsdDatatype datatype, int data_len, void *data); -static void cmd_queue_add_command(EfsdConnection *ec, EfsdCommand *com); -static void cmd_queue_process(EfsdConnection *ec); +static void libefsd_cmd_queue_add_command(EfsdConnection *ec, EfsdCommand *com); +static void libefsd_cmd_queue_process(EfsdConnection *ec); static char* -get_full_path(char *file) +libefsd_get_full_path(char *file) { char cwd[MAXPATHLEN]; char *result = NULL; @@ -124,7 +129,7 @@ static int -send_command(EfsdConnection *ec, EfsdCommand *com) +libefsd_send_command(EfsdConnection *ec, EfsdCommand *com) { D_ENTER; @@ -133,8 +138,8 @@ if (!efsd_queue_empty(ec->cmd_q)) { - cmd_queue_add_command(ec, com); - cmd_queue_process(ec); + libefsd_cmd_queue_add_command(ec, com); + libefsd_cmd_queue_process(ec); } else { @@ -145,7 +150,7 @@ D_RETURN_(-1); } - cmd_queue_add_command(ec, com); + libefsd_cmd_queue_add_command(ec, com); } } @@ -154,7 +159,7 @@ static EfsdCmdId -get_next_id(void) +libefsd_get_next_id(void) { static EfsdCmdId id_counter = 0; @@ -163,32 +168,24 @@ } -static EfsdCmdId -file_cmd(EfsdConnection *ec, EfsdCommandType type, - int num_files, char **files, - int num_options, EfsdOption *ops) +static EfsdCmdId +libefsd_file_cmd_absolute(EfsdConnection *ec, EfsdCommandType type, + int num_files, char **files, + int num_options, EfsdOption *ops) { char **full_files = NULL; int i, used_files; - EfsdCommand cmd; EfsdCmdId id; D_ENTER; - - if (!ec || !files) - D_RETURN_(-1); - - memset(&cmd, 0, sizeof(EfsdCommand)); - cmd.type = type; - cmd.efsd_file_cmd.id = get_next_id(); - + /* Array gets freed in efsd_cmd_cleanup() ... */ full_files = malloc(sizeof(char*) * num_files); /* Hook in full paths of all given files, if possible. */ for (i = 0, used_files = 0; i < num_files; i++) { - full_files[used_files] = get_full_path(files[i]); + full_files[used_files] = libefsd_get_full_path(files[i]); if (full_files[used_files]) used_files++; } @@ -202,13 +199,35 @@ FREE(full_files); D_RETURN_(-1); } - + full_files = realloc(full_files, sizeof(char*) * used_files); - num_files = used_files; } + id = libefsd_file_cmd(ec, type, used_files, full_files, num_options, ops); + + D_RETURN_(id); +} + + +static EfsdCmdId +libefsd_file_cmd(EfsdConnection *ec, EfsdCommandType type, + int num_files, char **files, + int num_options, EfsdOption *ops) +{ + EfsdCommand cmd; + EfsdCmdId id; + + D_ENTER; + + if (!ec || !files) + D_RETURN_(-1); + + memset(&cmd, 0, sizeof(EfsdCommand)); + + cmd.type = type; + cmd.efsd_file_cmd.id = libefsd_get_next_id(); cmd.efsd_file_cmd.num_files = num_files; - cmd.efsd_file_cmd.files = full_files; + cmd.efsd_file_cmd.files = files; /* Hook in any options: */ if ((num_options > 0) && (ops)) @@ -218,7 +237,7 @@ } /* And send it! */ - if (send_command(ec, &cmd) < 0) + if (libefsd_send_command(ec, &cmd) < 0) { efsd_cmd_cleanup(&cmd); D_RETURN_(-1); @@ -231,8 +250,8 @@ static EfsdCmdId -set_metadata_internal(EfsdConnection *ec, char *key, char *filename, - EfsdDatatype datatype, int data_len, void *data) +libefsd_set_metadata_internal(EfsdConnection *ec, char *key, char *filename, + EfsdDatatype datatype, int data_len, void *data) { EfsdCommand cmd; EfsdCmdId id; @@ -245,12 +264,12 @@ memset(&cmd, 0, sizeof(EfsdCommand)); cmd.type = EFSD_CMD_SETMETA; - cmd.efsd_set_metadata_cmd.id = get_next_id(); + cmd.efsd_set_metadata_cmd.id = libefsd_get_next_id(); cmd.efsd_set_metadata_cmd.datatype = datatype; cmd.efsd_set_metadata_cmd.data_len = data_len; cmd.efsd_set_metadata_cmd.data = data; cmd.efsd_set_metadata_cmd.key = strdup(key); - cmd.efsd_set_metadata_cmd.file = get_full_path(filename); + cmd.efsd_set_metadata_cmd.file = libefsd_get_full_path(filename); if (!cmd.efsd_set_metadata_cmd.file) goto error_return; @@ -265,7 +284,7 @@ } */ - if (send_command(ec, &cmd) < 0) + if (libefsd_send_command(ec, &cmd) < 0) goto error_return; id = cmd.efsd_set_metadata_cmd.id; @@ -279,7 +298,7 @@ static void -cmd_queue_add_command(EfsdConnection *ec, EfsdCommand *com) +libefsd_cmd_queue_add_command(EfsdConnection *ec, EfsdCommand *com) { EfsdCommand *com_copy; @@ -297,7 +316,7 @@ static void -cmd_queue_process(EfsdConnection *ec) +libefsd_cmd_queue_process(EfsdConnection *ec) { EfsdCommand *cmd; @@ -329,7 +348,8 @@ /* Efsd API starts here --------------------------------------------- */ -EfsdConnection * efsd_open(void) +EfsdConnection * +efsd_open(void) { struct sockaddr_un cli_sun; EfsdConnection *ec; @@ -374,7 +394,8 @@ } -int efsd_get_connection_fd(EfsdConnection *ec) +int +efsd_get_connection_fd(EfsdConnection *ec) { D_ENTER; @@ -385,7 +406,8 @@ } -int efsd_close(EfsdConnection *ec) +int +efsd_close(EfsdConnection *ec) { EfsdCommand cmd; @@ -397,7 +419,7 @@ memset(&cmd, 0, sizeof(EfsdCommand)); cmd.type = EFSD_CMD_CLOSE; - if (send_command(ec, &cmd) < 0) + if (libefsd_send_command(ec, &cmd) < 0) { D_RETURN_(-1); } @@ -490,7 +512,7 @@ if (!ec) D_RETURN_(-1); - cmd_queue_process(ec); + libefsd_cmd_queue_process(ec); D_RETURN_(efsd_queue_empty(ec->cmd_q)); } @@ -505,9 +527,9 @@ D_ENTER; if (ops) - result = file_cmd(ec, EFSD_CMD_REMOVE, num_files, files, ops->num_used, ops->ops); + result = libefsd_file_cmd_absolute(ec, EFSD_CMD_REMOVE, num_files, files, ops->num_used, ops->ops); else - result = file_cmd(ec, EFSD_CMD_REMOVE, num_files, files, 0, NULL); + result = libefsd_file_cmd_absolute(ec, EFSD_CMD_REMOVE, num_files, files, 0, NULL); FREE(ops); @@ -523,9 +545,9 @@ D_ENTER; if (ops) - result = file_cmd(ec, EFSD_CMD_MOVE, num_files, files, ops->num_used, ops->ops); + result = libefsd_file_cmd_absolute(ec, EFSD_CMD_MOVE, num_files, files, ops->num_used, ops->ops); else - result = file_cmd(ec, EFSD_CMD_MOVE, num_files, files, 0, NULL); + result = libefsd_file_cmd_absolute(ec, EFSD_CMD_MOVE, num_files, files, 0, NULL); FREE(ops); @@ -541,9 +563,9 @@ D_ENTER; if (ops) - result = file_cmd(ec, EFSD_CMD_COPY, num_files, files, ops->num_used, ops->ops); + result = libefsd_file_cmd_absolute(ec, EFSD_CMD_COPY, num_files, files, ops->num_used, ops->ops); else - result = file_cmd(ec, EFSD_CMD_COPY, num_files, files, 0, NULL); + result = libefsd_file_cmd_absolute(ec, EFSD_CMD_COPY, num_files, files, 0, NULL); FREE(ops); @@ -560,7 +582,7 @@ D_ENTER; files[0] = from_file; files[1] = to_file; - result = file_cmd(ec, EFSD_CMD_SYMLINK, 2, files, 0, NULL); + result = libefsd_file_cmd_absolute(ec, EFSD_CMD_SYMLINK, 2, files, 0, NULL); D_RETURN_(result); } @@ -575,9 +597,9 @@ D_ENTER; if (ops) - result = file_cmd(ec, EFSD_CMD_LISTDIR, 1, &dirname, ops->num_used, ops->ops); + result = libefsd_file_cmd_absolute(ec, EFSD_CMD_LISTDIR, 1, &dirname, ops->num_used, ops->ops); else - result = file_cmd(ec, EFSD_CMD_LISTDIR, 1, &dirname, 0, NULL); + result = libefsd_file_cmd_absolute(ec, EFSD_CMD_LISTDIR, 1, &dirname, 0, NULL); FREE(ops); @@ -589,7 +611,7 @@ efsd_makedir(EfsdConnection *ec, char *dirname) { D_ENTER; - D_RETURN_(file_cmd(ec, EFSD_CMD_MAKEDIR, 1, &dirname, 0, NULL)); + D_RETURN_(libefsd_file_cmd_absolute(ec, EFSD_CMD_MAKEDIR, 1, &dirname, 0, NULL)); } @@ -606,14 +628,14 @@ memset(&cmd, 0, sizeof(EfsdCommand)); cmd.type = EFSD_CMD_CHMOD; - cmd.efsd_chmod_cmd.id = get_next_id(); + cmd.efsd_chmod_cmd.id = libefsd_get_next_id(); cmd.efsd_chmod_cmd.mode = mode; - cmd.efsd_chmod_cmd.file = get_full_path(filename); + cmd.efsd_chmod_cmd.file = libefsd_get_full_path(filename); if (!cmd.efsd_chmod_cmd.file) goto error_return; - if (send_command(ec, &cmd) < 0) + if (libefsd_send_command(ec, &cmd) < 0) goto error_return; id = cmd.efsd_chmod_cmd.id; @@ -634,8 +656,8 @@ D_ENTER; - id = set_metadata_internal(ec, key, filename, datatype, - datalength, data); + id = libefsd_set_metadata_internal(ec, key, filename, datatype, + datalength, data); D_RETURN_(id); } @@ -649,8 +671,8 @@ D_ENTER; - id = set_metadata_internal(ec, key, filename, EFSD_INT, - sizeof(int), &val); + id = libefsd_set_metadata_internal(ec, key, filename, EFSD_INT, + sizeof(int), &val); D_RETURN_(id); } @@ -664,8 +686,8 @@ D_ENTER; - id = set_metadata_internal(ec, key, filename, EFSD_FLOAT, - sizeof(float), &val); + id = libefsd_set_metadata_internal(ec, key, filename, EFSD_FLOAT, + sizeof(float), &val); D_RETURN_(id); } @@ -679,8 +701,8 @@ D_ENTER; - id = set_metadata_internal(ec, key, filename, EFSD_STRING, - strlen(val) + 1, val); + id = libefsd_set_metadata_internal(ec, key, filename, EFSD_STRING, + strlen(val) + 1, val); D_RETURN_(id); } @@ -701,10 +723,10 @@ memset(&cmd, 0, sizeof(EfsdCommand)); cmd.type = EFSD_CMD_GETMETA; - cmd.efsd_get_metadata_cmd.id = get_next_id(); + cmd.efsd_get_metadata_cmd.id = libefsd_get_next_id(); cmd.efsd_get_metadata_cmd.datatype = datatype; cmd.efsd_get_metadata_cmd.key = strdup(key); - cmd.efsd_get_metadata_cmd.file = get_full_path(filename); + cmd.efsd_get_metadata_cmd.file = libefsd_get_full_path(filename); if (!cmd.efsd_get_metadata_cmd.file) goto error_return; @@ -719,7 +741,7 @@ } */ - if (send_command(ec, &cmd) < 0) + if (libefsd_send_command(ec, &cmd) < 0) goto error_return; id = cmd.efsd_get_metadata_cmd.id; @@ -737,15 +759,22 @@ { D_ENTER; - if ((ee->type != EFSD_EVENT_REPLY) || - (ee->efsd_reply_event.command.type != - EFSD_CMD_GETMETA)) + if (!ee) + D_RETURN_(0); + + if ((ee->type == EFSD_EVENT_REPLY) && + (ee->efsd_reply_event.command.type == EFSD_CMD_GETMETA)) + { + D_RETURN_(ee->efsd_reply_event.command. + efsd_get_metadata_cmd.datatype); + } + + if (ee->type == EFSD_EVENT_METADATA_CHANGE) { - D_RETURN_(0); + D_RETURN_(ee->efsd_metachange_event.datatype); } - D_RETURN_(ee->efsd_reply_event.command. - efsd_get_metadata_cmd.datatype); + D_RETURN_(0); } @@ -754,19 +783,26 @@ { D_ENTER; - if ((!val) || - (ee->type != EFSD_EVENT_REPLY) || - (ee->efsd_reply_event.command.type != - EFSD_CMD_GETMETA) || + if (!val || !ee) + D_RETURN_(0); + + if ((ee->type == EFSD_EVENT_REPLY) && + (ee->efsd_reply_event.command.type == EFSD_CMD_GETMETA) && (ee->efsd_reply_event.command. - efsd_get_metadata_cmd.datatype != EFSD_INT) - ) + efsd_get_metadata_cmd.datatype == EFSD_INT)) { - D_RETURN_(0); + *val = *((int*)ee->efsd_reply_event.data); + D_RETURN_(1); } - *val = *((int*)ee->efsd_reply_event.data); - D_RETURN_(1); + if ((ee->type == EFSD_EVENT_METADATA_CHANGE) && + (ee->efsd_metachange_event.datatype == EFSD_INT)) + { + *val = *((int*)ee->efsd_metachange_event.data); + D_RETURN_(1); + } + + D_RETURN_(0); } @@ -775,19 +811,26 @@ { D_ENTER; - if ((!val) || - (ee->type != EFSD_EVENT_REPLY) || - (ee->efsd_reply_event.command.type != - EFSD_CMD_GETMETA) || + if (!val || !ee) + D_RETURN_(0); + + if ((ee->type == EFSD_EVENT_REPLY) && + (ee->efsd_reply_event.command.type == EFSD_CMD_GETMETA) && (ee->efsd_reply_event.command. - efsd_get_metadata_cmd.datatype != EFSD_FLOAT) - ) + efsd_get_metadata_cmd.datatype == EFSD_FLOAT)) + { + *val = *((float*)ee->efsd_reply_event.data); + D_RETURN_(1); + } + + if ((ee->type == EFSD_EVENT_METADATA_CHANGE) && + (ee->efsd_metachange_event.datatype == EFSD_FLOAT)) { - D_RETURN_(0); + *val = *((float*)ee->efsd_metachange_event.data); + D_RETURN_(1); } - *val = *((float*)ee->efsd_reply_event.data); - D_RETURN_(1); + D_RETURN_(0); } @@ -796,50 +839,54 @@ { D_ENTER; - if ((ee->type != EFSD_EVENT_REPLY) || - (ee->efsd_reply_event.command.type != - EFSD_CMD_GETMETA) || + if (!ee) + D_RETURN_(NULL); + + if ((ee->type == EFSD_EVENT_REPLY) && + (ee->efsd_reply_event.command.type == EFSD_CMD_GETMETA) && (ee->efsd_reply_event.command. - efsd_get_metadata_cmd.datatype != EFSD_STRING) - ) + efsd_get_metadata_cmd.datatype == EFSD_STRING)) { - D_RETURN_(NULL); + D_RETURN_((char*)ee->efsd_reply_event.data); } + + if ((ee->type == EFSD_EVENT_METADATA_CHANGE) && + (ee->efsd_metachange_event.datatype == EFSD_STRING)) + { + D_RETURN_((char*)ee->efsd_metachange_event.data); + } - D_RETURN_(strdup((char*)ee->efsd_reply_event.data)); + D_RETURN_(NULL); } void * efsd_metadata_get_raw(EfsdEvent *ee, int *data_len) { - void *result; - D_ENTER; - if ((ee->type != EFSD_EVENT_REPLY) || - (ee->efsd_reply_event.command.type != - EFSD_CMD_GETMETA) || + if (!ee || !data_len) + D_RETURN_(NULL); + + if ((ee->type == EFSD_EVENT_REPLY) && + (ee->efsd_reply_event.command.type == EFSD_CMD_GETMETA) && (ee->efsd_reply_event.command. - efsd_get_metadata_cmd.datatype != EFSD_FLOAT) - ) + efsd_get_metadata_cmd.datatype == EFSD_RAW)) { - D_RETURN_(NULL); - } - - if (data_len) - { *data_len = ee->efsd_reply_event.data_len; + + D_RETURN_(ee->efsd_reply_event.data); } - if ((result = malloc(ee->efsd_reply_event.data_len)) == NULL) + if ((ee->type == EFSD_EVENT_METADATA_CHANGE) && + (ee->efsd_metachange_event.datatype == EFSD_RAW)) { - D_RETURN_(NULL); - } - - memcpy(result, ee->efsd_reply_event.data, ee->efsd_reply_event.data_len); + *data_len = ee->efsd_metachange_event.data_len; - D_RETURN_(result); + D_RETURN_(ee->efsd_metachange_event.data); + } + + D_RETURN_(NULL); } @@ -848,14 +895,18 @@ { D_ENTER; - if ((ee->type != EFSD_EVENT_REPLY) || - (ee->efsd_reply_event.command.type != - EFSD_CMD_GETMETA)) + if ((ee->type == EFSD_EVENT_REPLY) && + (ee->efsd_reply_event.command.type == EFSD_CMD_GETMETA)) { - D_RETURN_(NULL); + D_RETURN_((char*)ee->efsd_reply_event.command.efsd_get_metadata_cmd.key); } - D_RETURN_(ee->efsd_reply_event.command.efsd_get_metadata_cmd.key); + if (ee->type == EFSD_EVENT_METADATA_CHANGE) + { + D_RETURN_((char*)ee->efsd_metachange_event.key); + } + + D_RETURN_(NULL); } @@ -864,14 +915,18 @@ { D_ENTER; - if ((ee->type != EFSD_EVENT_REPLY) || - (ee->efsd_reply_event.command.type != - EFSD_CMD_GETMETA)) + if ((ee->type == EFSD_EVENT_REPLY) && + (ee->efsd_reply_event.command.type == EFSD_CMD_GETMETA)) { - D_RETURN_(NULL); + D_RETURN_((char*)ee->efsd_reply_event.command.efsd_get_metadata_cmd.file); + } + + if (ee->type == EFSD_EVENT_METADATA_CHANGE) + { + D_RETURN_((char*)ee->efsd_metachange_event.file); } - D_RETURN_(ee->efsd_reply_event.command.efsd_get_metadata_cmd.file); + D_RETURN_(NULL); } @@ -897,9 +952,9 @@ type = EFSD_CMD_STARTMON_FILE; if (ops) - result = file_cmd(ec, type, 1, &filename, ops->num_used, ops->ops); + result = libefsd_file_cmd_absolute(ec, type, 1, &filename, ops->num_used, ops->ops); else - result = file_cmd(ec, type, 1, &filename, 0, NULL); + result = libefsd_file_cmd_absolute(ec, type, 1, &filename, 0, NULL); FREE(ops); @@ -919,15 +974,51 @@ else type = EFSD_CMD_STOPMON_FILE; - D_RETURN_(file_cmd(ec, type, 1, &filename, 0, NULL)); + D_RETURN_(libefsd_file_cmd_absolute(ec, type, 1, &filename, 0, NULL)); } EfsdCmdId +efsd_start_monitor_metadata(EfsdConnection *ec, char *filename, char *key) +{ + char **file_key_pair = NULL; + + D_ENTER; + + if (!filename || !*filename || !key || !*key) + D_RETURN_(-1); + + file_key_pair = malloc(sizeof(char*) * 2); + file_key_pair[0] = libefsd_get_full_path(filename); + file_key_pair[1] = strdup(key); + + D_RETURN_(libefsd_file_cmd(ec, EFSD_CMD_STARTMON_META, 2, file_key_pair, 0, NULL)); +} + + +EfsdCmdId +efsd_stop_monitor_metadata(EfsdConnection *ec, char *filename, char *key) +{ + char **file_key_pair = NULL; + + D_ENTER; + + if (!filename || !*filename || !key || !*key) + D_RETURN_(-1); + + file_key_pair = malloc(sizeof(char*) * 2); + file_key_pair[0] = libefsd_get_full_path(filename); + file_key_pair[1] = strdup(key); + + D_RETURN_(libefsd_file_cmd(ec, EFSD_CMD_STOPMON_META, 2, file_key_pair, 0, NULL)); +} + + +EfsdCmdId efsd_stat(EfsdConnection *ec, char *filename) { D_ENTER; - D_RETURN_(file_cmd(ec, EFSD_CMD_STAT, 1, &filename, 0, NULL)); + D_RETURN_(libefsd_file_cmd_absolute(ec, EFSD_CMD_STAT, 1, &filename, 0, NULL)); } @@ -935,7 +1026,7 @@ efsd_lstat(EfsdConnection *ec, char *filename) { D_ENTER; - D_RETURN_(file_cmd(ec, EFSD_CMD_LSTAT, 1, &filename, 0, NULL)); + D_RETURN_(libefsd_file_cmd_absolute(ec, EFSD_CMD_LSTAT, 1, &filename, 0, NULL)); } @@ -943,7 +1034,7 @@ efsd_readlink(EfsdConnection *ec, char *filename) { D_ENTER; - D_RETURN_(file_cmd(ec, EFSD_CMD_READLINK, 1, &filename, 0, NULL)); + D_RETURN_(libefsd_file_cmd_absolute(ec, EFSD_CMD_READLINK, 1, &filename, 0, NULL)); } @@ -951,7 +1042,7 @@ efsd_get_filetype(EfsdConnection *ec, char *filename) { D_ENTER; - D_RETURN_(file_cmd(ec, EFSD_CMD_GETFILETYPE, 1, &filename, 0, NULL)); + D_RETURN_(libefsd_file_cmd_absolute(ec, EFSD_CMD_GETFILETYPE, 1, &filename, 0, NULL)); } @@ -1107,7 +1198,7 @@ char * -efsd_reply_filename(EfsdEvent *ee) +efsd_event_filename(EfsdEvent *ee) { D_ENTER; @@ -1117,6 +1208,9 @@ if (ee->type == EFSD_EVENT_FILECHANGE) D_RETURN_(ee->efsd_filechange_event.file); + if (ee->type == EFSD_EVENT_METADATA_CHANGE) + D_RETURN_(ee->efsd_metachange_event.file); + switch (ee->efsd_reply_event.command.type) { case EFSD_CMD_REMOVE: @@ -1153,7 +1247,7 @@ EfsdCmdId -efsd_reply_id(EfsdEvent *ee) +efsd_event_id(EfsdEvent *ee) { D_ENTER; @@ -1163,6 +1257,9 @@ if (ee->type == EFSD_EVENT_FILECHANGE) D_RETURN_(ee->efsd_filechange_event.id); + if (ee->type == EFSD_EVENT_METADATA_CHANGE) + D_RETURN_(ee->efsd_metachange_event.id); + switch (ee->efsd_reply_event.command.type) { case EFSD_CMD_REMOVE: @@ -1199,16 +1296,24 @@ void * -efsd_reply_data(EfsdEvent *ee) +efsd_event_data(EfsdEvent *ee) { D_ENTER; if (!ee) D_RETURN_(NULL); - - if (ee->type != EFSD_EVENT_REPLY) - D_RETURN_(NULL); - D_RETURN_(ee->efsd_reply_event.data); + switch (ee->type) + { + case EFSD_EVENT_REPLY: + D_RETURN_(ee->efsd_reply_event.data); + break; + case EFSD_EVENT_METADATA_CHANGE: + D_RETURN_(ee->efsd_metachange_event.data); + break; + default: + } + + D_RETURN_(NULL); } =================================================================== RCS file: /cvsroot/enlightenment/e17/apps/efsd/efsd/libefsd.h,v retrieving revision 1.43 retrieving revision 1.44 diff -u -3 -r1.43 -r1.44 --- libefsd.h 2001/11/16 16:44:15 1.43 +++ libefsd.h 2001/11/26 01:06:38 1.44 @@ -460,36 +460,37 @@ /** - * efsd_reply_filename - returns filename contained in an event. + * efsd_event_filename - returns filename contained in an event. * @ee: The EfsdEvent. * - * Convenience function to access the filenames in reply or - * filechange events. If the event is a reply event an... [truncated message content] |
From: <enl...@li...> - 2001-11-26 01:07:10
|
Enlightenment CVS committal Author : cpk Project : e17 Module : apps/efsd Dir : e17/apps/efsd/doc Modified Files: efsd-manual.sgml manual.raw Log Message: * Here's metadata monitoring. Details are in the manual and in libefsd's header file. * I'm using getpwuid() now instead of using $HOME to find a user's home directory. * The metadata access convenience calls in libefsd now behave as the manual says, i.e. they do not duplicate memory. Keep this in mind when you want to keep the data you receive around. * Updated doco accordingly. * Fixlets I cannot remember right now :) =================================================================== RCS file: /cvsroot/enlightenment/e17/apps/efsd/doc/efsd-manual.sgml,v retrieving revision 1.22 retrieving revision 1.23 diff -u -3 -r1.22 -r1.23 --- efsd-manual.sgml 2001/11/16 22:05:36 1.22 +++ efsd-manual.sgml 2001/11/26 01:06:37 1.23 @@ -160,7 +160,7 @@ </listitem> <listitem> <para> - Edb, the Enlightenment Database, based on BerkeleyDB. It's available on + Edb, the Enlightenment Database, based on Berkeley DB. It's available on Enlightenment's SourceForge <ulink url="http://prdownloads.sourceforge.net/enlightenment">download page</ulink>. </para> @@ -381,7 +381,7 @@ get the &efsd; connection file descriptor using <link linkend="API-efsd-get-connection-fd"><function>efsd_get_connection_fd()</function></link>, then to use <function>select()</function> on the file descriptor to - find out when it becomes writeable, and then flush the queue. + find out when it becomes writable, and then flush the queue. </para> </section> @@ -545,25 +545,57 @@ the concept. </para> - <mediaobject> - <imageobject> - <imagedata fileref="figures/efsd-event.eps" format="eps"> - </imageobject> - <imageobject> - <imagedata fileref="figures/efsd-event.gif" format="gif"> - </imageobject> - <textobject> - <phrase>Image of EfsdEvent structure</phrase> - </textobject> - <caption> - <para>The <classname>EfsdEvent</classname> Union.</para> - </caption> - </mediaobject> + <programlisting> ++---------------------------------------------------------+ +| EfsdEvent | +| | +| +---------------------------------------------------+ | +| | EfsdEventType type; | | +| +---------------------------------------------------+ | +| | +| +---------------------------------------------------+ | +| | EfsdFileChangeEvent efsd_filechange_event | | +| | | | +| | EfsdEventType type; | | +| | EfsdCmdId id; | | +| | EfsdFilechangeType changetype; | | +| | char * file; | | +| | | | +| +---------------------------------------------------+ | +| | +| +---------------------------------------------------+ | +| | EfsdMetadataChangeEvent efsd_metachange_event | | +| | | | +| | EfsdEventType type; | | +| | EfsdCmdId id; | | +| | char * key; | | +| | char * file; | | +| | EfsdDatatype datatype; | | +| | int data_len; | | +| | void * data; | | +| | | | +| +---------------------------------------------------+ | +| | +| +---------------------------------------------------+ | +| | EfsdReplyEvent efsd_reply_event | | +| | | | +| | EfsdEventType type; | | +| | EfsdCommand command; | | +| | int errorcode; | | +| | int data_len; | | +| | void * data; | | +| | | | +| +---------------------------------------------------+ | +| | ++---------------------------------------------------------+ + + </programlisting> <para> The <classname>EfsdEvent.type</classname> field can be used to determine the kind of event, either - <constant>EFSD_EVENT_FILECHANGE</constant> or <constant>EFSD_EVENT_REPLY</constant>. - In the former case, <classname>EfsdEvent.efsd_filechange_event.id</classname> contains + <constant>EFSD_EVENT_FILECHANGE</constant>, <constant>EFSD_EVENT_METADATA_CHANGE</constant> + or <constant>EFSD_EVENT_REPLY</constant>. + In the first case, <classname>EfsdEvent.efsd_filechange_event.id</classname> contains the command ID that caused this filechange event to be generated <footnote><para> Recall that you get the command ID whenever you issue an &efsd; command.</para></footnote>. <classname>EfsdEvent.efsd_filechange_event.changetype</classname> describes the type @@ -624,20 +656,51 @@ </para> </listitem> </itemizedlist> + + Finally, <classname>EfsdEvent.efsd_filechange_event.file</classname> contains + the canonical name of the file on which the event is reported. + </para> - Finally, <classname>EfsdEvent.file</classname> contains the canonical name of - the file on which the event is reported. + <para> + When <classname>EfsdEvent.type</classname> is <constant>EFSD_EVENT_METADATA_CHANGE</constant>, + you're dealing with a metadata change event. The meaning of the structure entries + is then as follows: <classname>EfsdEvent.efsd_metachange_event.id</classname> is + the command ID that was associated with the &efsd; command that requested the + monitoring, <classname>EfsdEvent.efsd_metachange_event.key</classname> and + <classname>EfsdEvent.efsd_metachange_event.file</classname> are the filename + that has the given metadata and the key of the metadata entry itself. + <classname>EfsdEvent.efsd_metachange_event.datatype</classname> is the type of the + metadata entry and is one of + + <itemizedlist mark="opencircle"> + <listitem> + <para><constant>EFSD_INT</constant>: integer data.</para> + </listitem> + <listitem> + <para><constant>EFSD_FLOAT</constant>: floating-point data.</para> + </listitem> + <listitem> + <para><constant>EFSD_STRING</constant>: character string data.</para> + </listitem> + <listitem> + <para><constant>EFSD_RAW</constant>: raw binary data.</para> + </listitem> + </itemizedlist> + + Finally, <classname>EfsdEvent.efsd_metachange_event.data_len</classname> and + <classname>EfsdEvent.efsd_metachange_event.data</classname> contain the length + of the changed metadata item and a pointer to the data itself. </para> <para> When <classname>EfsdEvent.type</classname> is <constant>EFSD_EVENT_REPLY</constant>, - <classname>EfsdEvent.command</classname> contains the command that caused this - reply event, <classname>EfsdEvent.errorcode</classname> is the result (a value of 0 + <classname>EfsdEvent.efsd_reply_event.command</classname> contains the command that caused this + reply event, <classname>EfsdEvent.efsd_reply_event.errorcode</classname> is the result (a value of 0 means the operation was completed successfully, otherwise the field contains the value of the <function>errno</function> variable and can be processed using <function>strerror</function> etc) of the command, - <classname>EfsdEvent.data_len</classname> is the length of any received binary data - in bytes, and <classname>EfsdEvent.data</classname> is a pointer to the data itself. + <classname>EfsdEvent.efsd_reply_event.data_len</classname> is the length of any received binary data + in bytes, and <classname>EfsdEvent.efsd_reply_event.data</classname> is a pointer to the data itself. </para> </section> @@ -784,6 +847,52 @@ </para> </section> + <section id="metamon"> + <title id="metamon.title">Monitoring Metadata</title> + <para> + In some occasions it's useful to know when a file's metadata changes. Therefore, + &efsd; also provides an API to monitor metadata. The monitoring does not rely + on the metadata database file to change on disk, because that would be bad for + at least two reasons -- + + <itemizedlist mark="opencircle"> + <listitem> + <para> + Metadata is not written to disk immediately. Therefore in most cases, the + notification about changed metadata would arrive later than necessary. + </para> + </listitem> + <listitem> + <para> + &efsd; itself is the instance that manages setting and retrieving metadata, + therefore it is easier to send out metadata change notifications + directly when they happen, namely, when a client's metadata setting + request is processed. + </para> + </listitem> + </itemizedlist> + + The functions responsible for metadata monitoring are simple to use, there is + <link linkend="API-efsd-start-monitor-metadata"><function>efsd_start_monitor_metadata</function></link> + to start monitoring a metadata entry, and + <link linkend="API-efsd-stop-monitor-metadata"><function>efsd_stop_monitor_metadata</function></link> + to stop the monitoring. You can monitor metadata entries that do not exist yet. + If a metadata item that is monitored gets changed by a a client, all clients + monitoring that metadata entry receive &efsd; events of type + <constant>EFSD_EVENT_METADATA_CHANGE</constant> that contain details about + the filename and the metadata that changed, along with the new metadata. + See the section on <link linkend="eventtypes">event types</link> for details. + + <note> + <title>You can use the convenience functions <function>efsd_metadata_...()</function> + for accessing the data in the metadata change events. Make sure to duplicate + pointers and data when you need to keep them around, because you just get + pointers into the structure. + <para></para> + </note> + </para> + </section> + <section id="filetypes"> <title id="filetypes.title">Handling Filetypes</title> <para> @@ -930,6 +1039,45 @@ </para> </section> + <section> + <title>Convenience Functions for Accessing Data in <classname>EfsdEvents</classname></title> + <para> + Walking through the structs of the <classname>EfsdEvent</classname> union + can be cumbersome, so there are a few helper functions that will return + entries that exits in all the event types, depending on the type of the + event. These are: + + <itemizedlist mark="opencircle"> + <listitem> + <para> + <link linkend="API-efsd-event-filename"><function>efsd_event_filename()</function></link> + returns the filename in an event. For filechange events, it returns + the name of the file that changed, for metadata change events, it's + the name of the file whose metadata changed, and for reply events, it's + the filename that was affected by the command. + </para> + </listitem> + <listitem> + <para> + <link linkend="API-efsd-event-id"><function>efsd_event_id()</function></link> + returns the command ID in an event. + </para> + </listitem> + <listitem> + <para> + <link linkend="API-efsd-event-data"><function>efsd_event_data()</function></link> + returns any data items returned in an event. For metadata change events, + it returns a pointer to the changed metadata, for reply events, a pointer + to <classname>EfsdEvent.efsd_reply_event.data</classname>, and NULL otherwise. + </para> + </listitem> + </itemizedlist> + + In any case, you just get a pointer into the structure, so you don't need to + free anything here. + </para> + </section> + <section id="options"> <title id="options.title">Passing Command Options</title> <para> @@ -2545,10 +2693,10 @@ <refentry> <refmeta> -<refentrytitle><phrase id="API-efsd-reply-filename">efsd_reply_filename</phrase></refentrytitle> +<refentrytitle><phrase id="API-efsd-event-filename">efsd_event_filename</phrase></refentrytitle> </refmeta> <refnamediv> - <refname>efsd_reply_filename</refname> + <refname>efsd_event_filename</refname> <refpurpose> returns filename contained in an event. </refpurpose> @@ -2556,7 +2704,7 @@ <refsynopsisdiv> <title>Synopsis</title> <funcsynopsis> - <funcdef>char * <function>efsd_reply_filename </function></funcdef> + <funcdef>char * <function>efsd_event_filename </function></funcdef> <paramdef>EfsdEvent * <parameter>ee</parameter></paramdef> </funcsynopsis> </refsynopsisdiv> @@ -2576,21 +2724,21 @@ <refsect1> <title>Description</title> <para> - Convenience function to access the filenames in reply or - filechange events. If the event is a reply event and the + Convenience function to access the filenames in received + events. If the event is a reply event and the contained command is an efsd_file_cmd, it returns the first file - (efsd_file_cmd.files[0]). Returns <constant>NULL</constant> if no file could be - found. + (efsd_file_cmd.files[0]). For filechange events, it returns + efsd_filechange_event.file. Returns <constant>NULL</constant> otherwise. </para> </refsect1> </refentry> <refentry> <refmeta> -<refentrytitle><phrase id="API-efsd-reply-id">efsd_reply_id</phrase></refentrytitle> +<refentrytitle><phrase id="API-efsd-event-id">efsd_event_id</phrase></refentrytitle> </refmeta> <refnamediv> - <refname>efsd_reply_id</refname> + <refname>efsd_event_id</refname> <refpurpose> returns command id contained in an event. </refpurpose> @@ -2598,7 +2746,7 @@ <refsynopsisdiv> <title>Synopsis</title> <funcsynopsis> - <funcdef>EfsdCmdId <function>efsd_reply_id </function></funcdef> + <funcdef>EfsdCmdId <function>efsd_event_id </function></funcdef> <paramdef>EfsdEvent * <parameter>ee</parameter></paramdef> </funcsynopsis> </refsynopsisdiv> @@ -2618,26 +2766,26 @@ <refsect1> <title>Description</title> <para> - Convenience function to access the command ID in reply or - filechange events. Returns -1 if no ID is contained in the event. + Convenience function to access the command ID in received + events. Returns -1 if no ID is contained in the event. </para> </refsect1> </refentry> <refentry> <refmeta> -<refentrytitle><phrase id="API-efsd-reply-data">efsd_reply_data</phrase></refentrytitle> +<refentrytitle><phrase id="API-efsd-event-data">efsd_event_data</phrase></refentrytitle> </refmeta> <refnamediv> - <refname>efsd_reply_data</refname> + <refname>efsd_event_data</refname> <refpurpose> - returns data contained in a reply event + returns data contained in a event </refpurpose> </refnamediv> <refsynopsisdiv> <title>Synopsis</title> <funcsynopsis> - <funcdef>void * <function>efsd_reply_data </function></funcdef> + <funcdef>void * <function>efsd_event_data </function></funcdef> <paramdef>EfsdEvent * <parameter>ee</parameter></paramdef> </funcsynopsis> </refsynopsisdiv> @@ -2657,8 +2805,9 @@ <refsect1> <title>Description</title> <para> - Convenience function access the data returned in a reply - event. Returns NULL if an error occured. + Convenience function access the data returned in a received + event. Returns NULL if the event does not contain any + returned data, or if the command is not applicable. </para> </refsect1> </refentry> @@ -2807,6 +2956,122 @@ <refentry> <refmeta> +<refentrytitle><phrase id="API-efsd-start-monitor-metadata">efsd_start_monitor_metadata</phrase></refentrytitle> +</refmeta> +<refnamediv> + <refname>efsd_start_monitor_metadata</refname> + <refpurpose> + starts monitoring metadata. + </refpurpose> +</refnamediv> +<refsynopsisdiv> + <title>Synopsis</title> + <funcsynopsis> + <funcdef>EfsdCmdId <function>efsd_start_monitor_metadata </function></funcdef> + <paramdef>EfsdConnection * <parameter>ec</parameter></paramdef> + <paramdef>char * <parameter>filename</parameter></paramdef> + <paramdef>char * <parameter>key</parameter></paramdef> + </funcsynopsis> +</refsynopsisdiv> +<refsect1> + <title>Arguments</title> + <variablelist> + <varlistentry> + <term><parameter>ec</parameter></term> + <listitem> + <para> + The Efsd connection. + </para> + </listitem> + </varlistentry> + <varlistentry> + <term><parameter>filename</parameter></term> + <listitem> + <para> + The file with metadata entries to be monitored. + </para> + </listitem> + </varlistentry> + <varlistentry> + <term><parameter>key</parameter></term> + <listitem> + <para> + The key of the metadata item that is to be monitored. + </para> + </listitem> + </varlistentry> + </variablelist> +</refsect1> +<refsect1> + <title>Description</title> + <para> + This command requests monitoring of the metadata associated + to the given <parameter>key</parameter> on the given <parameter>filename</parameter>. The client issuing + this command will receive events of type <constant>EFSD_EVENT_METADATA_CHANGE</constant> + when the specified metadata entry changes. + </para> +</refsect1> +</refentry> + +<refentry> +<refmeta> +<refentrytitle><phrase id="API-efsd-stop-monitor-metadata">efsd_stop_monitor_metadata</phrase></refentrytitle> +</refmeta> +<refnamediv> + <refname>efsd_stop_monitor_metadata</refname> + <refpurpose> + stops monitoring metadata. + </refpurpose> +</refnamediv> +<refsynopsisdiv> + <title>Synopsis</title> + <funcsynopsis> + <funcdef>EfsdCmdId <function>efsd_stop_monitor_metadata </function></funcdef> + <paramdef>EfsdConnection * <parameter>ec</parameter></paramdef> + <paramdef>char * <parameter>filename</parameter></paramdef> + <paramdef>char * <parameter>key</parameter></paramdef> + </funcsynopsis> +</refsynopsisdiv> +<refsect1> + <title>Arguments</title> + <variablelist> + <varlistentry> + <term><parameter>ec</parameter></term> + <listitem> + <para> + The Efsd connection. + </para> + </listitem> + </varlistentry> + <varlistentry> + <term><parameter>filename</parameter></term> + <listitem> + <para> + The file with a metadata entry that is monitored. + </para> + </listitem> + </varlistentry> + <varlistentry> + <term><parameter>key</parameter></term> + <listitem> + <para> + The key of the metadata item that no longer needs to be monitored. + </para> + </listitem> + </varlistentry> + </variablelist> +</refsect1> +<refsect1> + <title>Description</title> + <para> + This command stops monitoring of the metadata associated + to the given <parameter>key</parameter> on the given <parameter>filename</parameter>. + </para> +</refsect1> +</refentry> + +<refentry> +<refmeta> <refentrytitle><phrase id="API-efsd-stat">efsd_stat</phrase></refentrytitle> </refmeta> <refnamediv> @@ -3582,7 +3847,7 @@ </row> <row> <entry><filename>efsd_dynarray.[ch]</filename></entry> - <entry>A dynamic array of charachter strings that can + <entry>A dynamic array of character strings that can be sorted, inserted into etc.</entry> </row> <row> @@ -3698,6 +3963,663 @@ </para> </section> + <section id="efsd-code-docs"> + <title id="efsd-code-docs.title">&efsd; Code Documentation</title> +<refentry> +<refmeta> +<refentrytitle><phrase id="API-efsd-meta-set">efsd_meta_set</phrase></refentrytitle> +</refmeta> +<refnamediv> + <refname>efsd_meta_set</refname> + <refpurpose> + Metadata setting function. + </refpurpose> +</refnamediv> +<refsynopsisdiv> + <title>Synopsis</title> + <funcsynopsis> + <funcdef>int <function>efsd_meta_set </function></funcdef> + <paramdef>EfsdCommand * <parameter>ec</parameter></paramdef> + </funcsynopsis> +</refsynopsisdiv> +<refsect1> + <title>Arguments</title> + <variablelist> + <varlistentry> + <term><parameter>ec</parameter></term> + <listitem> + <para> + Efsd command + </para> + </listitem> + </varlistentry> + </variablelist> +</refsect1> +<refsect1> + <title>Description</title> + <para> + This function is called when a client wants to set metadata + on a file. + </para> +</refsect1> +</refentry> + +<refentry> +<refmeta> +<refentrytitle><phrase id="API-efsd-meta-get">efsd_meta_get</phrase></refentrytitle> +</refmeta> +<refnamediv> + <refname>efsd_meta_get</refname> + <refpurpose> + Metadata retrieval function. + </refpurpose> +</refnamediv> +<refsynopsisdiv> + <title>Synopsis</title> + <funcsynopsis> + <funcdef>void * <function>efsd_meta_get </function></funcdef> + <paramdef>EfsdCommand * <parameter>ec</parameter></paramdef> + <paramdef>int * <parameter>data_len</parameter></paramdef> + </funcsynopsis> +</refsynopsisdiv> +<refsect1> + <title>Arguments</title> + <variablelist> + <varlistentry> + <term><parameter>ec</parameter></term> + <listitem> + <para> + Efsd command + </para> + </listitem> + </varlistentry> + <varlistentry> + <term><parameter>data_len</parameter></term> + <listitem> + <para> + Result pointer that receives the length of the metadata chunk. + </para> + </listitem> + </varlistentry> + </variablelist> +</refsect1> +<refsect1> + <title>Description</title> + <para> + This function is called when a client wants to retrieve + metadata associated with a file. + </para> +</refsect1> +</refentry> + +<refentry> +<refmeta> +<refentrytitle><phrase id="API-efsd-meta-copy-data">efsd_meta_copy_data</phrase></refentrytitle> +</refmeta> +<refnamediv> + <refname>efsd_meta_copy_data</refname> + <refpurpose> + Copies metadata from one file to another. + </refpurpose> +</refnamediv> +<refsynopsisdiv> + <title>Synopsis</title> + <funcsynopsis> + <funcdef>int <function>efsd_meta_copy_data </function></funcdef> + <paramdef>char * <parameter>from_file</parameter></paramdef> + <paramdef>char * <parameter>to_file</parameter></paramdef> + </funcsynopsis> +</refsynopsisdiv> +<refsect1> + <title>Arguments</title> + <variablelist> + <varlistentry> + <term><parameter>from_file</parameter></term> + <listitem> + <para> + The file from which to copy the metadata + </para> + </listitem> + </varlistentry> + <varlistentry> + <term><parameter>to_file</parameter></term> + <listitem> + <para> + The file to which to add the metadata + </para> + </listitem> + </varlistentry> + </variablelist> +</refsect1> +<refsect1> + <title>Description</title> + <para> + This function copies metadata from one file to another, as + it is needed for example after copying files. + </para> +</refsect1> +</refentry> + +<refentry> +<refmeta> +<refentrytitle><phrase id="API-efsd-meta-move-data">efsd_meta_move_data</phrase></refentrytitle> +</refmeta> +<refnamediv> + <refname>efsd_meta_move_data</refname> + <refpurpose> + Moves metadata from one file to another. + </refpurpose> +</refnamediv> +<refsynopsisdiv> + <title>Synopsis</title> + <funcsynopsis> + <funcdef>int <function>efsd_meta_move_data </function></funcdef> + <paramdef>char * <parameter>from_file</parameter></paramdef> + <paramdef>char * <parameter>to_file</parameter></paramdef> + </funcsynopsis> +</refsynopsisdiv> +<refsect1> + <title>Arguments</title> + <variablelist> + <varlistentry> + <term><parameter>from_file</parameter></term> + <listitem> + <para> + The file from which to take the metadata + </para> + </listitem> + </varlistentry> + <varlistentry> + <term><parameter>to_file</parameter></term> + <listitem> + <para> + The file to which to add the metadata + </para> + </listitem> + </varlistentry> + </variablelist> +</refsect1> +<refsect1> + <title>Description</title> + <para> + This function moves metadata from one file to another, as + it is needed for example after moving files. + </para> +</refsect1> +</refentry> + +<refentry> +<refmeta> +<refentrytitle><phrase id="API-efsd-meta-remove-data">efsd_meta_remove_data</phrase></refentrytitle> +</refmeta> +<refnamediv> + <refname>efsd_meta_remove_data</refname> + <refpurpose> + Removes metadata for a file. + </refpurpose> +</refnamediv> +<refsynopsisdiv> + <title>Synopsis</title> + <funcsynopsis> + <funcdef>int <function>efsd_meta_remove_data </function></funcdef> + <paramdef>char * <parameter>file</parameter></paramdef> + </funcsynopsis> +</refsynopsisdiv> +<refsect1> + <title>Arguments</title> + <variablelist> + <varlistentry> + <term><parameter>file</parameter></term> + <listitem> + <para> + The file whose metadata needs to be removed. + </para> + </listitem> + </varlistentry> + </variablelist> +</refsect1> +<refsect1> + <title>Description</title> + <para> + This function removes all metadata associated with a file. + </para> +</refsect1> +</refentry> + +<refentry> +<refmeta> +<refentrytitle><phrase id="API-efsd-meta-dir-cleanup">efsd_meta_dir_cleanup</phrase></refentrytitle> +</refmeta> +<refnamediv> + <refname>efsd_meta_dir_cleanup</refname> + <refpurpose> + Cleans up empty directories. + </refpurpose> +</refnamediv> +<refsynopsisdiv> + <title>Synopsis</title> + <funcsynopsis> + <funcdef>void <function>efsd_meta_dir_cleanup </function></funcdef> + <paramdef>char * <parameter>dir</parameter></paramdef> + </funcsynopsis> +</refsynopsisdiv> +<refsect1> + <title>Arguments</title> + <variablelist> + <varlistentry> + <term><parameter>dir</parameter></term> + <listitem> + <para> + Directory to clean up. + </para> + </listitem> + </varlistentry> + </variablelist> +</refsect1> +<refsect1> + <title>Description</title> + <para> + This function checks whether the given file contains + any real files (files other than <quote>.</quote>, <quote>..</quote> and the metadata + directory), and if not, removes the metadata directory. + </para> +</refsect1> +</refentry> + +<refentry> +<refmeta> +<refentrytitle><phrase id="API-efsd-meta-idle">efsd_meta_idle</phrase></refentrytitle> +</refmeta> +<refnamediv> + <refname>efsd_meta_idle</refname> + <refpurpose> + Idlehandler for metadata module + </refpurpose> +</refnamediv> +<refsynopsisdiv> + <title>Synopsis</title> + <funcsynopsis> + <funcdef>void <function>efsd_meta_idle </function></funcdef> + <paramdef> <parameter>void</parameter></paramdef> + </funcsynopsis> +</refsynopsisdiv> +<refsect1> + <title>Arguments</title> + <variablelist> + <varlistentry> + <term><parameter>void</parameter></term> + <listitem> + <para> + </para> + </listitem> + </varlistentry> + </variablelist> +</refsect1> +<refsect1> + <title>Description</title> + <para> + </para><para> + + This function is an idlehandler that tries to flush + the metadata db settings to disk. + </para> +</refsect1> +</refentry> + +<refentry> +<refmeta> +<refentrytitle><phrase id="API-efsd-meta-get-file-info">efsd_meta_get_file_info</phrase></refentrytitle> +</refmeta> +<refnamediv> + <refname>efsd_meta_get_file_info</refname> + <refpurpose> + Returns info about metadata for a file + </refpurpose> +</refnamediv> +<refsynopsisdiv> + <title>Synopsis</title> + <funcsynopsis> + <funcdef>int <function>efsd_meta_get_file_info </function></funcdef> + <paramdef>char * <parameter>filename</parameter></paramdef> + <paramdef>char * <parameter>dbfile</parameter></paramdef> + <paramdef>int <parameter>db_len</parameter></paramdef> + <paramdef>char * <parameter>key</parameter></paramdef> + <paramdef>int <parameter>key_len</parameter></paramdef> + <paramdef>int <parameter>create</parameter></paramdef> + </funcsynopsis> +</refsynopsisdiv> +<refsect1> + <title>Arguments</title> + <variablelist> + <varlistentry> + <term><parameter>filename</parameter></term> + <listitem> + <para> + The full path name of the file. + </para> + </listitem> + </varlistentry> + <varlistentry> + <term><parameter>dbfile</parameter></term> + <listitem> + <para> + Result pointer to location of db file for <parameter>filename</parameter>. + </para> + </listitem> + </varlistentry> + <varlistentry> + <term><parameter>db_len</parameter></term> + <listitem> + <para> + Length of string to write result into. + </para> + </listitem> + </varlistentry> + <varlistentry> + <term><parameter>key</parameter></term> + <listitem> + <para> + Result pointer to metadata key prefix for <parameter>filename</parameter>. + </para> + </listitem> + </varlistentry> + <varlistentry> + <term><parameter>key_len</parameter></term> + <listitem> + <para> + Length of string to write result into. + </para> + </listitem> + </varlistentry> + <varlistentry> + <term><parameter>create</parameter></term> + <listitem> + <para> + Flag which causes the metadata directory to be created if it doesn't exist yet. + </para> + </listitem> + </varlistentry> + </variablelist> +</refsect1> +<refsect1> + <title>Description</title> + <para> + This is a helper function that looks at the given + filename and returns the location of the metadata + db file and the key prefix that depends on the location + of the file (it can be just the file name or the full + path). + </para><para> + + Returns TRUE if operation was successfull, FALSE otherwise. + </para> +</refsect1> +</refentry> + +<refentry> +<refmeta> +<refentrytitle><phrase id="API-efsd-meta-monitor-init">efsd_meta_monitor_init</phrase></refentrytitle> +</refmeta> +<refnamediv> + <refname>efsd_meta_monitor_init</refname> + <refpurpose> + Initializer function. + </refpurpose> +</refnamediv> +<refsynopsisdiv> + <title>Synopsis</title> + <funcsynopsis> + <funcdef>void <function>efsd_meta_monitor_init </function></funcdef> + <paramdef> <parameter>void</parameter></paramdef> + </funcsynopsis> +</refsynopsisdiv> +<refsect1> + <title>Arguments</title> + <variablelist> + <varlistentry> + <term><parameter>void</parameter></term> + <listitem> + <para> + </para> + </listitem> + </varlistentry> + </variablelist> +</refsect1> +<refsect1> + <title>Description</title> + <para> + </para><para> + + This function sets up everything necessary to monitor + metadata entries. + </para> +</refsect1> +</refentry> + +<refentry> +<refmeta> +<refentrytitle><phrase id="API-efsd-meta-monitor-add">efsd_meta_monitor_add</phrase></refentrytitle> +</refmeta> +<refnamediv> + <refname>efsd_meta_monitor_add</refname> + <refpurpose> + Adds a client to a metadata monitor. + </refpurpose> +</refnamediv> +<refsynopsisdiv> + <title>Synopsis</title> + <funcsynopsis> + <funcdef>int <function>efsd_meta_monitor_add </function></funcdef> + <paramdef>EfsdCommand * <parameter>cmd</parameter></paramdef> + <paramdef>int <parameter>client</parameter></paramdef> + </funcsynopsis> +</refsynopsisdiv> +<refsect1> + <title>Arguments</title> + <variablelist> + <varlistentry> + <term><parameter>cmd</parameter></term> + <listitem> + <para> + EfsdCommand that contains the request. + </para> + </listitem> + </varlistentry> + <varlistentry> + <term><parameter>client</parameter></term> + <listitem> + <para> + Client which requested the monitor. + </para> + </listitem> + </varlistentry> + </variablelist> +</refsect1> +<refsect1> + <title>Description</title> + <para> + This function established metadata monitoring for a given + client. The file and key are stored in the commnd. If no + monitor for the file/key combination exists yet, it is + created, otherwise the client is simply added to the monitor. + </para><para> + + Returns TRUE when successful, FALSE otherwise. + </para> +</refsect1> +</refentry> + +<refentry> +<refmeta> +<refentrytitle><phrase id="API-efsd-meta-monitor-del">efsd_meta_monitor_del</phrase></refentrytitle> +</refmeta> +<refnamediv> + <refname>efsd_meta_monitor_del</refname> + <refpurpose> + Removes a client to a metadata monitor. + </refpurpose> +</refnamediv> +<refsynopsisdiv> + <title>Synopsis</title> + <funcsynopsis> + <funcdef>int <function>efsd_meta_monitor_del </function></funcdef> + <paramdef>EfsdCommand * <parameter>cmd</parameter></paramdef> + <paramdef>int <parameter>client</parameter></paramdef> + </funcsynopsis> +</refsynopsisdiv> +<refsect1> + <title>Arguments</title> + <variablelist> + <varlistentry> + <term><parameter>cmd</parameter></term> + <listitem> + <para> + EfsdCommand that contains the request. + </para> + </listitem> + </varlistentry> + <varlistentry> + <term><parameter>client</parameter></term> + <listitem> + <para> + Client which requested the monitoring stop. + </para> + </listitem> + </varlistentry> + </variablelist> +</refsect1> +<refsect1> + <title>Description</title> + <para> + This function stops metadata monitoring for a given + client and file/key. The file and key are stored in the commnd. + If no monitor for the file/key combination exists, the + function simply returns, otherwise the client is removed + from the monitor. + </para><para> + + Returns TRUE when successful, FALSE otherwise. + </para> +</refsect1> +</refentry> + +<refentry> +<refmeta> +<refentrytitle><phrase id="API-efsd-meta-monitor-notify">efsd_meta_monitor_notify</phrase></refentrytitle> +</refmeta> +<refnamediv> + <refname>efsd_meta_monitor_notify</refname> + <refpurpose> + Reports changed metadata. + </refpurpose> +</refnamediv> +<refsynopsisdiv> + <title>Synopsis</title> + <funcsynopsis> + <funcdef>void <function>efsd_meta_monitor_notify </function></funcdef> + <paramdef>char * <parameter>file</parameter></paramdef> + <paramdef>char * <parameter>key</parameter></paramdef> + <paramdef>EfsdDatatype <parameter>type</parameter></paramdef> + <paramdef>int <parameter>data_len</parameter></paramdef> + <paramdef>void * <parameter>data</parameter></paramdef> + </funcsynopsis> +</refsynopsisdiv> +<refsect1> + <title>Arguments</title> + <variablelist> + <varlistentry> + <term><parameter>file</parameter></term> + <listitem> + <para> + The file whose metadata changed. + </para> + </listitem> + </varlistentry> + <varlistentry> + <term><parameter>key</parameter></term> + <listitem> + <para> + The metadata that changed. + </para> + </listitem> + </varlistentry> + <varlistentry> + <term><parameter>type</parameter></term> + <listitem> + <para> + The type of the modified data. + </para> + </listitem> + </varlistentry> + <varlistentry> + <term><parameter>data_len</parameter></term> + <listitem> + <para> + The length of the new metadata. + </para> + </listitem> + </varlistentry> + <varlistentry> + <term><parameter>data</parameter></term> + <listitem> + <para> + The new metadata. + </para> + </listitem> + </varlistentry> + </variablelist> +</refsect1> +<refsect1> + <title>Description</title> + <para> + This function is called when a metadata entry changed, + and causes metadata change events to be sent to all + monitoring clients. + </para> +</refsect1> +</refentry> + +<refentry> +<refmeta> +<refentrytitle><phrase id="API-efsd-meta-monitor-cleanup-client">efsd_meta_monitor_cleanup_client</phrase></refentrytitle> +</refmeta> +<refnamediv> + <refname>efsd_meta_monitor_cleanup_client</refname> + <refpurpose> + Remove all monitors for a client. + </refpurpose> +</refnamediv> +<refsynopsisdiv> + <title>Synopsis</title> + <funcsynopsis> + <funcdef>void <function>efsd_meta_monitor_cleanup_client </function></funcdef> + <paramdef>int <parameter>client</parameter></paramdef> + </funcsynopsis> +</refsynopsisdiv> +<refsect1> + <title>Arguments</title> + <variablelist> + <varlistentry> + <term><parameter>client</parameter></term> + <listitem> + <para> + The client that no longer exists. + </para> + </listitem> + </varlistentry> + </variablelist> +</refsect1> +<refsect1> + <title>Description</title> + <para> + This function is called when the connection to a client ends. + It cleans up all monitors that this client had still registered. + </para> +</refsect1> +</refentry> + + </section> + <!-- <section id="efsd-ipc"> @@ -3757,7 +4679,7 @@ </para> <para> Besides being useful for testing &efsd; commands, &efsdsh; is also great for testing &efsd;'s - behaviour when handling multiple clients - just launch a bunch of &efsdsh;s and watch how + behavior when handling multiple clients - just launch a bunch of &efsdsh;s and watch how file monitoring requests are answered in a few of them etc. </para> <para> =================================================================== RCS file: /cvsroot/enlightenment/e17/apps/efsd/doc/manual.raw,v retrieving revision 1.3 retrieving revision 1.4 diff -u -3 -r1.3 -r1.4 --- manual.raw 2001/11/16 22:05:36 1.3 +++ manual.raw 2001/11/26 01:06:37 1.4 @@ -160,7 +160,7 @@ </listitem> <listitem> <para> - Edb, the Enlightenment Database, based on BerkeleyDB. It's available on + Edb, the Enlightenment Database, based on Berkeley DB. It's available on Enlightenment's SourceForge <ulink url="http://prdownloads.sourceforge.net/enlightenment">download page</ulink>. </para> @@ -381,7 +381,7 @@ get the &efsd; connection file descriptor using <link linkend="API-efsd-get-connection-fd"><function>efsd_get_connection_fd()</function></link>, then to use <function>select()</function> on the file descriptor to - find out when it becomes writeable, and then flush the queue. + find out when it becomes writable, and then flush the queue. </para> </section> @@ -545,25 +545,57 @@ the concept. </para> - <mediaobject> - <imageobject> - <imagedata fileref="figures/efsd-event.eps" format="eps"> - </imageobject> - <imageobject> - <imagedata fileref="figures/efsd-event.gif" format="gif"> - </imageobject> - <textobject> - <phrase>Image of EfsdEvent structure</phrase> - </textobject> - <caption> - <para>The <classname>EfsdEvent</classname> Union.</para> - </caption> - </mediaobject> + <programlisting> ++---------------------------------------------------------+ +| EfsdEvent | +| | +| +---------------------------------------------------+ | +| | EfsdEventType type; | | +| +---------------------------------------------------+ | +| | +| +---------------------------------------------------+ | +| | EfsdFileChangeEvent efsd_filechange_event | | +| | | | +| | EfsdEventType type; | | +| | EfsdCmdId id; | | +| | EfsdFilechangeType changetype; | | +| | char * file; | | +| | | | +| +---------------------------------------------------+ | +| | +| +---------------------------------------------------+ | +| | EfsdMetadataChangeEvent efsd_metachange_event | | +| | | | +| | EfsdEventType type; | | +| | EfsdCmdId id; | | +| | char * key; | | +| | char * file; | | +| | EfsdDatatype datatype; | | +| | int data_len; | | +| | void * data; | | +| | | | +| +---------------------------------------------------+ | +| | +| +---------------------------------------------------+ | +| | EfsdReplyEvent efsd_reply_event | | +| | | | +| | EfsdEventType type; | | +| | EfsdCommand command; | | +| | int errorcode; | | +| | int data_len; | | +| | void * data; | | +| | | | +| +---------------------------------------------------+ | +| | ++---------------------------------------------------------+ + + </programlisting> <para> The <classname>EfsdEvent.type</classname> field can be used to determine the kind of event, either - <constant>EFSD_EVENT_FILECHANGE</constant> or <constant>EFSD_EVENT_REPLY</constant>. - In the former case, <classname>EfsdEvent.efsd_filechange_event.id</classname> contains + <constant>EFSD_EVENT_FILECHANGE</constant>, <constant>EFSD_EVENT_METADATA_CHANGE</constant> + or <constant>EFSD_EVENT_REPLY</constant>. + In the first case, <classname>EfsdEvent.efsd_filechange_event.id</classname> contains the command ID that caused this filechange event to be generated <footnote><para> Recall that you get the command ID whenever you issue an &efsd; command.</para></footnote>. <classname>EfsdEvent.efsd_filechange_event.changetype</classname> describes the type @@ -625,19 +657,50 @@ </listitem> </itemizedlist> - Finally, <classname>EfsdEvent.file</classname> contains the canonical name of - the file on which the event is reported. + Finally, <classname>EfsdEvent.efsd_filechange_event.file</classname> contains + the canonical name of the file on which the event is reported. </para> <para> + When <classname>EfsdEvent.type</classname> is <constant>EFSD_EVENT_METADATA_CHANGE</constant>, + you're dealing with a metadata change event. The meaning of the structure entries + is then as follows: <classname>EfsdEvent.efsd_metachange_event.id</classname> is + the command ID that was associated with the &efsd; command that requested the + monitoring, <classname>EfsdEvent.efsd_metachange_event.key</classname> and + <classname>EfsdEvent.efsd_metachange_event.file</classname> are the filename + that has the given metadata and the key of the metadata entry itself. + <classname>EfsdEvent.efsd_metachange_event.datatype</classname> is the type of the + metadata entry and is one of + + <itemizedlist mark="opencircle"> + <listitem> + <para><constant>EFSD_INT</constant>: integer data.</para> + </listitem> + <listitem> + <para><constant>EFSD_FLOAT</constant>: floating-point data.</para> + </listitem> + <listitem> + <para><constant>EFSD_STRING</constant>: character string data.</para> + </listitem> + <listitem> + <para><constant>EFSD_RAW</constant>: raw binary data.</para> + </listitem> + </itemizedlist> + + Finally, <classname>EfsdEvent.efsd_metachange_event.data_len</classname> and + <classname>EfsdEvent.efsd_metachange_event.data</classname> contain the length + of the changed metadata item and a pointer to the data itself. + </para> + + <para> When <classname>EfsdEvent.type</classname> is <constant>EFSD_EVENT_REPLY</constant>, - <classname>EfsdEvent.command</classname> contains the command that caused this - reply event, <classname>EfsdEvent.errorcode</classname> is the result (a value of 0 + <classname>EfsdEvent.efsd_reply_event.command</classname> contains the command that caused this + reply event, <classname>EfsdEvent.efsd_reply_event.errorcode</classname> is the result (a value of 0 means the operation was completed successfully, otherwise the field contains the value of the <function>errno</function> variable and can be processed using <function>strerror</function> etc) of the command, - <classname>EfsdEvent.data_len</classname> is the length of any received binary data - in bytes, and <classname>EfsdEvent.data</classname> is a pointer to the data itself. + <classname>EfsdEvent.efsd_reply_event.data_len</classname> is the length of any received binary data + in bytes, and <classname>EfsdEvent.efsd_reply_event.data</classname> is a pointer to the data itself. </para> </section> @@ -784,6 +847,52 @@ </para> </section> + <section id="metamon"> + <title id="metamon.title">Monitoring Metadata</title> + <para> + In some occasions it's useful to know when a file's metadata changes. Therefore, + &efsd; also provides an API to monitor metadata. The monitoring does not rely + on the metadata database file to change on disk, because that would be bad for + at least two reasons -- + + <itemizedlist mark="opencircle"> + <listitem> + <para> + Metadata is not written to disk immediately. Therefore in most cases, the + notification about changed metadata would arrive later than necessary. + </para> + </listitem> + <listitem> + <para> + &efsd; itself is the instance that manages setting and retrieving metadata, + therefore it is easier to send out metadata change notifications + directly when they happen, namely, when a client's metadata setting + request is processed. + </para> + </listitem> + </itemizedlist> + + The functions responsible for metadata monitoring are simple to use, there is + <link linkend="API-efsd-start-monitor-metadata"><function>efsd_start_monitor_metadata</function></link> + to start monitoring a metadata entry, and + <link linkend="API-efsd-stop-monitor-metadata"><function>efsd_stop_monitor_metadata</function></link> + to stop the monitoring. You can monitor metadata entries that do not exist yet. + If a metadata item that is monitored gets changed by a a client, all clients + monitoring that metadata entry receive &efsd; events of type + <constant>EFSD_EVENT_METADATA_CHANGE</constant> that contain details about + the filename and the metadata that changed, along with the new metadata. + See the section on <link linkend="eventtypes">event types</link> for details. + + <note> + <title>You can use the convenience functions <function>efsd_metadata_...()</function> + for accessing the data in the metadata change events. Make sure to duplicate + pointers and data when you need to keep them around, because you just get + pointers into the structure. + <para></para> + </note> + </para> + </section> + <section id="filetypes"> <title id="filetypes.title">Handling Filetypes</title> <para> @@ -930,6 +1039,45 @@ </para> </section> + <section> + <title>Convenience Functions for Accessing Data in <classname>EfsdEvents</classname></title> + <para> + Walking through the structs of the <classname>EfsdEvent</classname> union + can be cumbersome, so there are a few helper functions that will return + entries that exits in all the event types, depending on the type of the + event. These are: + + <itemizedlist mark="opencircle"> + <listitem> + <para> + <link linkend="API-efsd-event-filename"><function>efsd_event_filename()</function></link> + returns the filename in an event. For filechange events, it returns + the name of the file that changed, for metadata change events, it's + the name of the file whose metadata changed, and for reply events, it's + the filename that was affected by the command. + </para> + </listitem> + <listitem> + <para> + <link linkend="API-efsd-event-id"><function>efsd_event_id()</function></link> + returns the command ID in an event. + </para> + </listitem> + <listitem> + <para> + <link linkend="API-efsd-event-data"><function>efsd_event_data()</function></link> + returns any data items returned in an event. For metadata change events, + it returns a pointer to the changed metadata, for reply events, a pointer + to <classname>EfsdEvent.efsd_reply_event.data</classname>, and NULL otherwise. + </para> + </listitem> + </itemizedlist> + + In any case, you just get a pointer into the structure, so you don't need to + free anything here. + </para> + </section> + <section id="options"> <title id="options.title">Passing Command Options</title> <para> @@ -1182,7 +1330,7 @@ </row> <row> <entry><filename>efsd_dynarray.[ch]</filename></entry> - <entry>A dynamic array of charachter strings that can + <entry>A dynamic array of character strings that can be sorted, inserted into etc.</entry> </row> <row> @@ -1298,6 +1446,12 @@ </para> </section> + <section id="efsd-code-docs"> + <title id="efsd-code-docs.title">&efsd; Code Documentation</title> +!Iefsd/efsd_meta.h +!Iefsd/efsd_meta_monitor.h + </section> + <!-- <section id="efsd-ipc"> @@ -1357,7 +1511,7 @@ </para> <para> Besides being useful for testing &efsd; commands, &efsdsh; is also great for testing &efsd;'s - behaviour when handling multiple clients - just launch a bunch of &efsdsh;s and watch how + behavior when handling multiple clients - just launch a bunch of &efsdsh;s and watch how file monitoring requests are answered in a few of them etc. </para> <para> |
From: <enl...@li...> - 2001-12-02 22:25:10
|
Enlightenment CVS committal Author : cpk Project : e17 Module : apps/efsd Dir : e17/apps/efsd/efsd Modified Files: efsd_monitor.c Log Message: Better logic for clearer code ... =================================================================== RCS file: /cvsroot/enlightenment/e17/apps/efsd/efsd/efsd_monitor.c,v retrieving revision 1.21 retrieving revision 1.22 diff -u -3 -r1.21 -r1.22 --- efsd_monitor.c 2001/11/26 01:06:38 1.21 +++ efsd_monitor.c 2001/12/02 22:25:09 1.22 @@ -550,54 +550,34 @@ else { EfsdMonitorRequest *emr; - EfsdList *l2; + EfsdList *l; /* Use count not zero -- remove given client from list of monitoring clients. */ - for (l2 = efsd_list_head(m->clients); l2; l2 = efsd_list_next(l2)) + for (l = efsd_list_head(m->clients); l; l = efsd_list_next(l)) { - emr = (EfsdMonitorRequest*)efsd_list_data(l2); + emr = (EfsdMonitorRequest*)efsd_list_data(l); if (emr->client != client) continue; + + if (client == EFSD_CLIENT_INTERNAL && m->internal_use_count > 0) + break; + + D("Use count on %s is (%i/%i) -- removing client %i.\n", + m->filename, m->internal_use_count, m->client_use_count, client); - if (client == EFSD_CLIENT_INTERNAL) + if (!m->is_receiving_exist_events) { - if (m->internal_use_count == 0) - { - D("Use count on %s is (%i/%i) -- removing internal.\n", - m->filename, m->internal_use_count, m->client_use_count); - - if (!m->is_receiving_exist_events) - { - m->clients = efsd_list_remove(m->clients, l2, - (EfsdFunc)efsd_monitor_request_free); - } - else - { - D("Client %i is currently receiving exist events. Marking as finished.\n", client); - emr->is_finished = TRUE; - } - } + m->clients = efsd_list_remove(m->clients, l, + (EfsdFunc)efsd_monitor_request_free); } else { - D("Use count on %s is (%i/%i) -- removing client %i.\n", - m->filename, m->internal_use_count, m->client_use_count, client); - - if (!m->is_receiving_exist_events) - { - m->clients = efsd_list_remove(m->clients, l2, - (EfsdFunc)efsd_monitor_request_free); - } - else - { - D("Client %i is currently receiving exist events. Marking as finished.\n", client); - emr->is_finished = TRUE; - } + D("Client %i is currently receiving exist events. Marking as finished.\n", client); + emr->is_finished = TRUE; } - l2 = NULL; break; } } |
From: <enl...@li...> - 2001-12-06 23:06:05
|
Enlightenment CVS committal Author : cpk Project : e17 Module : apps/efsd Dir : e17/apps/efsd/efsd Modified Files: efsd_commands.c efsd_event_queue.c efsd_event_queue.h efsd_fs.c efsd_globals.h efsd_main.c efsd_main.h efsd_meta_monitor.c efsd_monitor.c efsd_statcache.c Log Message: * proper handling of EOF returned from recvmsg() when a client shut down. Keeps Efsd from eating 100& cpu in some cases. * fixes when copying symlinks. Also a readlink() fix for efsd_readlink(). * removed the array of the client fds from the global variables, instead using efsd_main_get_fd() now, and updated calls accordingly. Much nicer in case I need to go move to poll() to make things more robust. =================================================================== RCS file: /cvsroot/enlightenment/e17/apps/efsd/efsd/efsd_commands.c,v retrieving revision 1.13 retrieving revision 1.14 diff -u -3 -r1.13 -r1.14 --- efsd_commands.c 2001/11/26 01:06:38 1.13 +++ efsd_commands.c 2001/12/06 23:06:04 1.14 @@ -77,7 +77,7 @@ D_ENTER; - sockfd = clientfd[client]; + sockfd = efsd_main_get_fd(client); if (sockfd < 0) D_RETURN_(-1); @@ -98,7 +98,7 @@ if (errno == EPIPE) efsd_main_close_connection(client); else - efsd_event_queue_add_event(ev_q, sockfd, &ee); + efsd_event_queue_add_event(ev_q, client, &ee); D_RETURN_(-1); } @@ -470,6 +470,7 @@ if ((n = readlink(cmd->efsd_file_cmd.files[0], s, MAXPATHLEN)) >= 0) { + s[n] = '\0'; result = send_reply(cmd, 0, n, s, client); } else =================================================================== RCS file: /cvsroot/enlightenment/e17/apps/efsd/efsd/efsd_event_queue.c,v retrieving revision 1.3 retrieving revision 1.4 diff -u -3 -r1.3 -r1.4 --- efsd_event_queue.c 2001/10/12 17:31:47 1.3 +++ efsd_event_queue.c 2001/12/06 23:06:04 1.4 @@ -94,18 +94,20 @@ { EfsdQueueIterator *eqi; EfsdEventQItem *qi; + int fd; D_ENTER; for (eqi = efsd_queue_it_new(q); efsd_queue_it_valid(eqi); efsd_queue_it_next(eqi)) { qi = (EfsdEventQItem*) efsd_queue_it_item(eqi); + fd = efsd_main_get_fd(qi->client); - if (qi->client > 0) + if (fd > 0) { - FD_SET(qi->client, fdset); - if (qi->client > *fdsize) - *fdsize = qi->client; + FD_SET(fd, fdset); + if (fd > *fdsize) + *fdsize = fd; } } @@ -120,7 +122,7 @@ { EfsdQueueIterator *eqi; EfsdEventQItem *qi; - int done = 0; + int fd, done = 0; D_ENTER; @@ -136,8 +138,9 @@ for (eqi = efsd_queue_it_new(q); efsd_queue_it_valid(eqi); efsd_queue_it_next(eqi)) { qi = (EfsdEventQItem*) efsd_queue_it_item(eqi); + fd = efsd_main_get_fd(qi->client); - if (qi->client < 0) + if (fd < 0) { efsd_queue_it_remove(eqi); event_queue_item_free(qi); @@ -145,9 +148,10 @@ continue; } - if (FD_ISSET(qi->client, fdset)) + + if (FD_ISSET(fd, fdset)) { - if (efsd_io_write_event(qi->client, qi->ee) < 0) + if (efsd_io_write_event(fd, qi->ee) < 0) { if (errno == EPIPE) { @@ -180,7 +184,7 @@ void -efsd_event_queue_add_event(EfsdQueue *q, int sockfd, EfsdEvent *ee) +efsd_event_queue_add_event(EfsdQueue *q, int client, EfsdEvent *ee) { EfsdEvent *ee_copy; @@ -188,7 +192,7 @@ ee_copy = NEW(EfsdEvent); efsd_event_duplicate(ee, ee_copy); - efsd_queue_append_item(q, event_queue_item_new(sockfd, ee_copy)); + efsd_queue_append_item(q, event_queue_item_new(client, ee_copy)); D_RETURN; } =================================================================== RCS file: /cvsroot/enlightenment/e17/apps/efsd/efsd/efsd_event_queue.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -3 -r1.1 -r1.2 --- efsd_event_queue.h 2001/09/30 18:35:07 1.1 +++ efsd_event_queue.h 2001/12/06 23:06:04 1.2 @@ -45,6 +45,6 @@ /* Adds an event that is supposed to be delivered to SOCKFD, making a copy of event EE. */ -void efsd_event_queue_add_event(EfsdQueue *q, int sockfd, EfsdEvent *ee); +void efsd_event_queue_add_event(EfsdQueue *q, int client, EfsdEvent *ee); #endif =================================================================== RCS file: /cvsroot/enlightenment/e17/apps/efsd/efsd/efsd_fs.c,v retrieving revision 1.12 retrieving revision 1.13 diff -u -3 -r1.12 -r1.13 --- efsd_fs.c 2001/11/16 16:44:15 1.12 +++ efsd_fs.c 2001/12/06 23:06:04 1.13 @@ -227,21 +227,24 @@ if (S_ISLNK(src_st->st_mode)) { char realfile[MAXPATHLEN]; + int length; - if (readlink(src_path, realfile, MAXPATHLEN) < 0) + if ((length = readlink(src_path, realfile, MAXPATHLEN)) < 0) { perror("Readlink error"); success = FALSE; } + /* Terminate the thing, dammit. */ + realfile[length] = '\0'; + if (realfile[0] != '/') { char realcopy[MAXPATHLEN]; char *lastslash; - strncpy(realcopy, realfile, MAXPATHLEN); - strncpy(realfile, src_path, MAXPATHLEN); - lastslash = strrchr(realfile, '/'); + snprintf(realcopy, MAXPATHLEN, src_path); + lastslash = strrchr(realcopy, '/'); if (!lastslash) { @@ -250,7 +253,8 @@ exit(-1); } - strncpy(lastslash+1, realcopy, MAXPATHLEN - (lastslash - realfile)); + snprintf(lastslash + 1, MAXPATHLEN - (lastslash - realcopy), "%s", realfile); + snprintf(realfile, MAXPATHLEN, realcopy); } if (symlink(realfile, dst_path) < 0) @@ -260,9 +264,12 @@ perror("Symlink error"); success = FALSE; } - - D("Created symlink from %s to %s.\n", - realfile, dst_path); + else + { + success = TRUE; + D("Created symlink from %s to %s.\n", + realfile, dst_path); + } } else if (S_ISFIFO(src_st->st_mode)) { @@ -703,7 +710,7 @@ continue; } - + /* Otherwise, copy single regular file. */ if (!file_copy(src_path, &src_st, dst_path)) D_RETURN_(FALSE); =================================================================== RCS file: /cvsroot/enlightenment/e17/apps/efsd/efsd/efsd_globals.h,v retrieving revision 1.5 retrieving revision 1.6 diff -u -3 -r1.5 -r1.6 --- efsd_globals.h 2001/09/30 18:35:07 1.5 +++ efsd_globals.h 2001/12/06 23:06:04 1.6 @@ -30,7 +30,6 @@ #include <efsd_queue.h> extern FAMConnection famcon; -extern int clientfd[EFSD_CLIENTS]; extern int listen_fd; extern mode_t mode_755; =================================================================== RCS file: /cvsroot/enlightenment/e17/apps/efsd/efsd/efsd_main.c,v retrieving revision 1.51 retrieving revision 1.52 diff -u -3 -r1.51 -r1.52 --- efsd_main.c 2001/11/26 01:06:38 1.51 +++ efsd_main.c 2001/12/06 23:06:04 1.52 @@ -67,8 +67,6 @@ /* The connection to FAM */ FAMConnection famcon; -/* File desciptors for connected clients */ -int clientfd[EFSD_CLIENTS]; /* Command line options: */ char opt_foreground = FALSE; @@ -78,6 +76,10 @@ EfsdQueue *ev_q; +/* File desciptors for connected clients */ +static int clientfd[EFSD_CLIENTS]; + + /* File descriptor for accepting new clients */ static int listen_fd; static char app_cmd[MAXPATHLEN]; @@ -661,7 +663,7 @@ static void main_handle_connections(void) { - struct sockaddr_un serv_sun, cli_sun; + struct sockaddr_un serv_sun; int num_read, fdsize, clilen, i, n, can_accept, sock_fd; fd_set fdrset; fd_set fdwset; @@ -770,6 +772,7 @@ */ tv.tv_sec = 1; tv.tv_usec = 0; + while ((n = select(fdsize+1, &fdrset, fdwset_ptr, NULL, &tv)) < 0) { if (errno == EINTR) @@ -836,12 +839,15 @@ else { efsd_cmd_free(ecmd); + efsd_main_close_connection(i); } } } if (FD_ISSET(listen_fd, &fdrset)) { + struct sockaddr_un cli_sun; + /* There's a new client connecting -- register it. */ clilen = sizeof(cli_sun); if ( (sock_fd = accept(listen_fd, (struct sockaddr *)&cli_sun, &clilen)) < 0) @@ -1195,6 +1201,16 @@ } } D_RETURN; +} + + +int +efsd_main_get_fd(int client) +{ + if (client < 0 || client >= EFSD_CLIENTS) + D_RETURN_(-1); + + D_RETURN_(clientfd[client]); } =================================================================== RCS file: /cvsroot/enlightenment/e17/apps/efsd/efsd/efsd_main.h,v retrieving revision 1.2 retrieving revision 1.3 diff -u -3 -r1.2 -r1.3 --- efsd_main.h 2001/06/19 00:02:00 1.2 +++ efsd_main.h 2001/12/06 23:06:04 1.3 @@ -27,6 +27,7 @@ #include <efsd_monitor.h> +int efsd_main_get_fd(int client); int efsd_main_close_connection(int client); void efsd_main_handle_file_exists_options(char *filename, EfsdMonitorRequest *emr); =================================================================== RCS file: /cvsroot/enlightenment/e17/apps/efsd/efsd/efsd_meta_monitor.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -3 -r1.1 -r1.2 --- efsd_meta_monitor.c 2001/11/26 01:06:38 1.1 +++ efsd_meta_monitor.c 2001/12/06 23:06:04 1.2 @@ -329,7 +329,7 @@ D("Sending metadata change event for %s:%s to %i\n", monitor->filename, monitor->key, emr->client); - if (efsd_io_write_event(clientfd[emr->client], &ee) < 0) + if (efsd_io_write_event(efsd_main_get_fd(emr->client), &ee) < 0) { if (errno == EPIPE) { @@ -338,7 +338,7 @@ } else { - efsd_event_queue_add_event(ev_q, clientfd[emr->client], &ee); + efsd_event_queue_add_event(ev_q, emr->client, &ee); D("write() error when writing metadata change event.\n"); } } =================================================================== RCS file: /cvsroot/enlightenment/e17/apps/efsd/efsd/efsd_monitor.c,v retrieving revision 1.22 retrieving revision 1.23 diff -u -3 -r1.22 -r1.23 --- efsd_monitor.c 2001/12/02 22:25:09 1.22 +++ efsd_monitor.c 2001/12/06 23:06:04 1.23 @@ -402,7 +402,7 @@ static int monitor_add_client(EfsdMonitor *m, EfsdCommand *com, int client) { - EfsdList *l2 = NULL; + EfsdList *l = NULL; EfsdMonitorRequest *emr; D_ENTER; @@ -410,9 +410,9 @@ if (!m) D_RETURN_(FALSE); - for (l2 = efsd_list_head(m->clients); l2; l2 = efsd_list_next(l2)) + for (l = efsd_list_head(m->clients); l; l = efsd_list_next(l)) { - if (((EfsdMonitorRequest*)efsd_list_data(l2))->client == client) + if (((EfsdMonitorRequest*)efsd_list_data(l))->client == client) { LOCK(&m->use_count_mutex); if (client == EFSD_CLIENT_INTERNAL) @@ -424,7 +424,7 @@ } else { - efsd_monitor_send_filechange_events(m, (EfsdMonitorRequest*)efsd_list_data(l2)); + efsd_monitor_send_filechange_events(m, (EfsdMonitorRequest*)efsd_list_data(l)); D("Client %i already monitors %s\n", client, m->filename); } UNLOCK(&m->use_count_mutex); @@ -906,7 +906,7 @@ famev.code, emr->client); */ - if (efsd_io_write_event(clientfd[emr->client], &ee) < 0) + if (efsd_io_write_event(efsd_main_get_fd(emr->client), &ee) < 0) { if (errno == EPIPE) { @@ -915,7 +915,7 @@ } else { - efsd_event_queue_add_event(ev_q, clientfd[emr->client], &ee); + efsd_event_queue_add_event(ev_q, emr->client, &ee); D("write() error when writing FAM event.\n"); } =================================================================== RCS file: /cvsroot/enlightenment/e17/apps/efsd/efsd/efsd_statcache.c,v retrieving revision 1.17 retrieving revision 1.18 diff -u -3 -r1.17 -r1.18 --- efsd_statcache.c 2001/11/16 16:44:15 1.17 +++ efsd_statcache.c 2001/12/06 23:06:04 1.18 @@ -165,14 +165,12 @@ } else { - if (stat(filename, &(it->st)) < 0) + if ((stat(filename, &(it->st)) < 0) && + (lstat(filename, &(it->st)) < 0)) { - if (lstat(filename, &(it->st)) < 0) - { - D("stat and lstat() on %s failed.\n", filename); - FREE(it); - D_RETURN_(FALSE); - } + D("stat and lstat() on %s failed.\n", filename); + FREE(it); + D_RETURN_(FALSE); } } |
From: <enl...@li...> - 2001-12-18 13:37:05
|
Enlightenment CVS committal Author : cpk Project : e17 Module : apps/efsd Dir : e17/apps/efsd Modified Files: efsd-config.in Log Message: Ah. efsd-config gave libs and headers as if we were building efsd itself, not just for libefsd. Fixed. =================================================================== RCS file: /cvsroot/enlightenment/e17/apps/efsd/efsd-config.in,v retrieving revision 1.3 retrieving revision 1.4 diff -u -3 -r1.3 -r1.4 --- efsd-config.in 2001/08/23 14:05:38 1.3 +++ efsd-config.in 2001/12/18 13:37:04 1.4 @@ -42,11 +42,11 @@ if test @includedir@ != /usr/include ; then includes=-I@includedir@ fi - echo $includes @xml2_cflags@ @edb_cflags@ -I$prefix/include @PTHREAD_CFLAGS@ + echo $includes -I$prefix/include @PTHREAD_CFLAGS@ ;; --libs) libdirs=-L@libdir@ - echo $libdirs -lefsd @xml2_libs@ @edb_libs@ -lm @PTHREAD_LIB@ + echo $libdirs -lefsd -lm @PTHREAD_LIB@ ;; *) echo "${usage}" 1>&2 |
From: <enl...@li...> - 2001-12-21 00:01:52
|
Enlightenment CVS committal Author : cpk Project : e17 Module : apps/efsd Dir : e17/apps/efsd/efsd Modified Files: libefsd.c Log Message: Mhmmm okay. I noticed that when I moved some stuff around in libefsd a while ago, I accidentally disabled monitoring of single files. That's fixed now. But I see very inconsistent behavior when monitoring single files with fam, both in Efsd and other test apps. Basically, sometimes I just get the file-exists event for the file, but no change events afterwards. If I stop the monitor, stop the fam client (again no matter whether it's efsd or not) and restart it, it usually works. I'll need to check if this is fixed in the newer fam releases, I'm still on fam 2.6.4. =================================================================== RCS file: /cvsroot/enlightenment/e17/apps/efsd/efsd/libefsd.c,v retrieving revision 1.55 retrieving revision 1.56 diff -u -3 -r1.55 -r1.56 --- libefsd.c 2001/11/26 01:06:38 1.55 +++ libefsd.c 2001/12/21 00:01:51 1.56 @@ -943,7 +943,7 @@ if (lstat(filename, &st) < 0) D_RETURN_(-1); - if (!S_ISDIR(st.st_mode)) + if (dir_mode && !S_ISDIR(st.st_mode)) D_RETURN_(-1); if (dir_mode) |
From: <enl...@li...> - 2002-01-10 19:33:51
|
Enlightenment CVS committal Author : cpk Project : e17 Module : apps/efsd Dir : e17/apps/efsd Modified Files: TODO Log Message: A few things for me to look into when I'll be back on the block. =================================================================== RCS file: /cvsroot/enlightenment/e17/apps/efsd/TODO,v retrieving revision 1.6 retrieving revision 1.7 diff -u -3 -r1.6 -r1.7 --- TODO 2001/07/11 20:33:28 1.6 +++ TODO 2002/01/10 19:33:49 1.7 @@ -2,3 +2,9 @@ similar to that of file(1), ideally with i18n. * implement a comprehensive test suite. + +* File types have a bug that under some circumstances + produce the result document/unknown instead of the + correct one. Bug in the MF heuristic? + +* Issues with monitoring of single files? imon? |
From: <enl...@li...> - 2002-01-14 14:25:12
|
Enlightenment CVS committal Author : cpk Project : e17 Module : apps/efsd Dir : e17/apps/efsd Modified Files: TODO Log Message: More work ... =================================================================== RCS file: /cvsroot/enlightenment/e17/apps/efsd/TODO,v retrieving revision 1.7 retrieving revision 1.8 diff -u -3 -r1.7 -r1.8 --- TODO 2002/01/10 19:33:49 1.7 +++ TODO 2002/01/14 14:25:09 1.8 @@ -8,3 +8,6 @@ correct one. Bug in the MF heuristic? * Issues with monitoring of single files? imon? + +* Update efsd_misc_get_user_dir() to also use getpwuid() + instead of getenv("HOME"). |
From: <enl...@li...> - 2002-02-22 12:04:09
|
Enlightenment CVS committal Author : cpk Project : e17 Module : apps/efsd Dir : e17/apps/efsd Modified Files: TODO Log Message: More things to do ... =================================================================== RCS file: /cvsroot/enlightenment/e17/apps/efsd/TODO,v retrieving revision 1.8 retrieving revision 1.9 diff -u -3 -r1.8 -r1.9 --- TODO 14 Jan 2002 14:25:09 -0000 1.8 +++ TODO 22 Feb 2002 12:04:09 -0000 1.9 @@ -1,3 +1,8 @@ + +These are open issues to work on, in no particular order: +========================================================= + + * implement file information retrieval, with results similar to that of file(1), ideally with i18n. @@ -8,6 +13,16 @@ correct one. Bug in the MF heuristic? * Issues with monitoring of single files? imon? + Test dnotify. * Update efsd_misc_get_user_dir() to also use getpwuid() instead of getenv("HOME"). + +* Move socket file to /tmp to avoid problems when + home is nfs-shared. + +* Unmounting of e.g. cdroms not working because Efsd + keeps monitors around? + +* Add event callbacks to libefsd to be able to register + handlers instead of having to use switch-case statements. |
From: <enl...@li...> - 2002-04-15 22:09:32
|
Enlightenment CVS committal Author : cpk Project : e17 Module : apps/efsd Dir : e17/apps/efsd/doc Modified Files: Tag: SPLIT efsd-manual.sgml Log Message: AAAAAAAAHHH new code :) * Fixed reporting of dead links -- a dangling symlink is correctly reported as dead-link/unknown-fs again. Seems I broke that a while ago. * Prefixed the inclusion path for the libxml2 headers with "libxml" to fix the issues reported by Alan. * Fixed a race condition in the filetype move-to-front heuristic: under high load it was possible that a matching magic description got moved to the front of the list while other checks where iterating over the list already, the matching filetype was thus not found. * efsd_misc_get_user_dir() also uses getpwuid to find out the home dir. * Moved the socket file to /tmp to avoid issues with nfs-mounted homes, as Raster had pointed out. * Added an event callback interface to libefsd to be able to register handlers instead of having to use switch-case statements. Added management code to libefsd to make these handlers per-monitor. This is completely untested yet and will probably blow up right into your face :) * Fixed a bug in efsdsh, -ls actually performs an lstat() now. =================================================================== RCS file: /cvsroot/enlightenment/e17/apps/efsd/doc/efsd-manual.sgml,v retrieving revision 1.23 retrieving revision 1.23.2.1 diff -u -3 -r1.23 -r1.23.2.1 --- efsd-manual.sgml 26 Nov 2001 01:06:37 -0000 1.23 +++ efsd-manual.sgml 15 Apr 2002 22:09:00 -0000 1.23.2.1 @@ -1411,6 +1411,51 @@ <refentry> <refmeta> +<refentrytitle><phrase id="API-efsd-dispatch-event">efsd_dispatch_event</phrase></refentrytitle> +</refmeta> +<refnamediv> + <refname>efsd_dispatch_event</refname> + <refpurpose> + handles events through the dispatching mechanism. + </refpurpose> +</refnamediv> +<refsynopsisdiv> + <title>Synopsis</title> + <funcsynopsis> + <funcdef>int <function>efsd_dispatch_event </function></funcdef> + <paramdef>EfsdEvent * <parameter>ev</parameter></paramdef> + </funcsynopsis> +</refsynopsisdiv> +<refsect1> + <title>Arguments</title> + <variablelist> + <varlistentry> + <term><parameter>ev</parameter></term> + <listitem> + <para> + The Efsd event to dispatch. + </para> + </listitem> + </varlistentry> + </variablelist> +</refsect1> +<refsect1> + <title>Description</title> + <para> + This function looks up the set of callbacks for the command ID contained + in the event, and then dispatches this event to the appropriate callback. + If no set of callbacks is found or the matching callback isn't defined + in the EfsdEventCallbacks struct, nothing happens. + </para><para> + + Returns -1 when an error occurs, FALSE when the event didn't get + dispatched, and TRUE when it got dispatched. + </para> +</refsect1> +</refentry> + +<refentry> +<refmeta> <refentrytitle><phrase id="API-efsd-wait-event">efsd_wait_event</phrase></refentrytitle> </refmeta> <refnamediv> @@ -3711,6 +3756,131 @@ This option constructor returns an EfsdOption that causes Efsd to send <constant>EFSD_FILE_EXISTS</constant> also for hidden files (starting with a '.'). + </para> +</refsect1> +</refentry> + +<refentry> +<refmeta> +<refentrytitle><phrase id="API-efsd-callbacks-create">efsd_callbacks_create</phrase></refentrytitle> +</refmeta> +<refnamediv> + <refname>efsd_callbacks_create</refname> + <refpurpose> + returns an initialized event callback struct. + </refpurpose> +</refnamediv> +<refsynopsisdiv> + <title>Synopsis</title> + <funcsynopsis> + <funcdef>EfsdEventCallbacks * <function>efsd_callbacks_create </function></funcdef> + <paramdef> <parameter>void</parameter></paramdef> + </funcsynopsis> +</refsynopsisdiv> +<refsect1> + <title>Arguments</title> + <variablelist> + <varlistentry> + <term><parameter>void</parameter></term> + <listitem> + <para> + </para> + </listitem> + </varlistentry> + </variablelist> +</refsect1> +<refsect1> + <title>Description</title> + <para> + </para> +</refsect1> +</refentry> + +<refentry> +<refmeta> +<refentrytitle><phrase id="API-efsd-callbacks-cleanup">efsd_callbacks_cleanup</phrase></refentrytitle> +</refmeta> +<refnamediv> + <refname>efsd_callbacks_cleanup</refname> + <refpurpose> + cleans up memory occupied by a callbacks struct. + </refpurpose> +</refnamediv> +<refsynopsisdiv> + <title>Synopsis</title> + <funcsynopsis> + <funcdef>void <function>efsd_callbacks_cleanup </function></funcdef> + <paramdef>EfsdEventCallbacks * <parameter>callbacks</parameter></paramdef> + </funcsynopsis> +</refsynopsisdiv> +<refsect1> + <title>Arguments</title> + <variablelist> + <varlistentry> + <term><parameter>callbacks</parameter></term> + <listitem> + <para> + callbacks structure to clean up. + </para> + </listitem> + </varlistentry> + </variablelist> +</refsect1> +</refentry> + +<refentry> +<refmeta> +<refentrytitle><phrase id="API-efsd-callbacks-register">efsd_callbacks_register</phrase></refentrytitle> +</refmeta> +<refnamediv> + <refname>efsd_callbacks_register</refname> + <refpurpose> + registers a set of handlers for a particular monitor. + </refpurpose> +</refnamediv> +<refsynopsisdiv> + <title>Synopsis</title> + <funcsynopsis> + <funcdef>EfsdEventCallbacks * <function>efsd_callbacks_register </function></funcdef> + <paramdef>EfsdCmdId <parameter>id</parameter></paramdef> + <paramdef>EfsdEventCallbacks * <parameter>callbacks</parameter></paramdef> + </funcsynopsis> +</refsynopsisdiv> +<refsect1> + <title>Arguments</title> + <variablelist> + <varlistentry> + <term><parameter>id</parameter></term> + <listitem> + <para> + Command ID of the monitoring request. + </para> + </listitem> + </varlistentry> + <varlistentry> + <term><parameter>callbacks</parameter></term> + <listitem> + <para> + Initialized callback set. + </para> + </listitem> + </varlistentry> + </variablelist> +</refsect1> +<refsect1> + <title>Description</title> + <para> + You can register a set of event handlers for a particular file monitor + here. Pass the command ID that was returned by the corresponding + monitor request call as first argument, and an EfsdEventCallback struct + that is initialized properly second. You don't need to initialize + callbacks you don't want to use. + </para><para> + + If you want to change the set of callbacks for an ID, just call this + function again, you'll get the old set in return (and NULL otherwise). + Similarly, if you want to remove a callback set for a command ID, just + pass NULL as the second argument. </para> </refsect1> </refentry> |
From: <enl...@li...> - 2002-04-15 22:09:33
|
Enlightenment CVS committal Author : cpk Project : e17 Module : apps/efsd Dir : e17/apps/efsd/efsd Modified Files: Tag: SPLIT Makefile.am efsd_filetype.c efsd_hash.c efsd_hash.h efsd_main.c efsd_meta_monitor.c efsd_misc.c efsd_misc.h efsd_monitor.c efsd_statcache.c libefsd.c libefsd.h libefsd_misc.c Log Message: AAAAAAAAHHH new code :) * Fixed reporting of dead links -- a dangling symlink is correctly reported as dead-link/unknown-fs again. Seems I broke that a while ago. * Prefixed the inclusion path for the libxml2 headers with "libxml" to fix the issues reported by Alan. * Fixed a race condition in the filetype move-to-front heuristic: under high load it was possible that a matching magic description got moved to the front of the list while other checks where iterating over the list already, the matching filetype was thus not found. * efsd_misc_get_user_dir() also uses getpwuid to find out the home dir. * Moved the socket file to /tmp to avoid issues with nfs-mounted homes, as Raster had pointed out. * Added an event callback interface to libefsd to be able to register handlers instead of having to use switch-case statements. Added management code to libefsd to make these handlers per-monitor. This is completely untested yet and will probably blow up right into your face :) * Fixed a bug in efsdsh, -ls actually performs an lstat() now. =================================================================== RCS file: /cvsroot/enlightenment/e17/apps/efsd/efsd/Makefile.am,v retrieving revision 1.28 retrieving revision 1.28.2.1 diff -u -3 -r1.28 -r1.28.2.1 --- Makefile.am 26 Nov 2001 01:06:38 -0000 1.28 +++ Makefile.am 15 Apr 2002 22:09:01 -0000 1.28.2.1 @@ -57,6 +57,7 @@ efsd_types.h efsd_types.c \ efsd_queue.h libefsd_queue.c \ efsd_list.h efsd_list.c \ + efsd_hash.h efsd_hash.c \ libefsd_misc.h libefsd_misc.c \ libefsd.c =================================================================== RCS file: /cvsroot/enlightenment/e17/apps/efsd/efsd/efsd_filetype.c,v retrieving revision 1.34 retrieving revision 1.34.2.1 diff -u -3 -r1.34 -r1.34.2.1 --- efsd_filetype.c 26 Nov 2001 01:06:38 -0000 1.34 +++ efsd_filetype.c 15 Apr 2002 22:09:01 -0000 1.34.2.1 @@ -49,20 +49,13 @@ #include <fnmatch.h> /* libxml stuff */ -#include <tree.h> -#include <parser.h> +#include <libxml/tree.h> +#include <libxml/parser.h> #ifdef __EMX__ #include <strings.h> #endif -#ifdef DEBUG -#undef DEBUG -#endif - -#ifdef DEBUG_NEST -#undef DEBUG_NEST -#endif #include <efsd.h> #include <efsd_debug.h> @@ -198,6 +191,9 @@ */ static EfsdMagic sys_magic; static EfsdMagic user_magic; + +/* Mhmm well ideally there should be separate locking for + user magic and system-wide magic ... */ static EfsdLock *magic_lock; /* Filename patterns */ @@ -251,6 +247,8 @@ static void filetype_magic_add_child(EfsdMagic *em_dad, EfsdMagic *em_kid); static void filetype_magic_move_match_to_front(EfsdMagic *dad, EfsdMagic *kid); +static char *filetype_magic_test_toplevel(EfsdMagic *em, FILE *f, + char *ptr, EfsdMagic **matching_kid); static char *filetype_magic_test_level(EfsdMagic *em, FILE *f, char *ptr, char stop_when_found, EfsdMagic **matching_kid); @@ -1341,6 +1339,25 @@ } +/* This is a wrapper call to filetype_magic_test_level() that + is intended for calls to the root level of the magic tree + structure. It protects access to the tree through readlocks. +*/ +static char * +filetype_magic_test_toplevel(EfsdMagic *level, FILE *f, + char *ptr, EfsdMagic **matching_kid) +{ + char *result = NULL; + + D_ENTER; + + efsd_lock_get_read_access(magic_lock); + result = filetype_magic_test_level(level, f, ptr, TRUE, matching_kid); + efsd_lock_release_read_access(magic_lock); + + D_RETURN_(result); +} + static char * filetype_magic_test_level(EfsdMagic *level, FILE *f, char *ptr, char stop_when_found, @@ -1588,9 +1605,28 @@ if (!st) D_RETURN_(FALSE); + /* First, determine the basic file type, and if it's a link, check + whether it's dead or not. Then, look up the type of the fs that + the file lives on. The result is something like "dir/ext2". + */ if (S_ISLNK(st->st_mode)) { + char real[MAXPATHLEN]; + int real_len = 0; + + if ( (real_len = readlink(filename, real, real_len) >= 0)) + { + real[real_len] = '\0'; + + if (!efsd_misc_file_exists(real)) + broken_link = TRUE; + } + else + { + broken_link = TRUE; + } + if (broken_link) snprintf(type, len, "%s", "broken-link"); else @@ -1634,33 +1670,14 @@ snprintf(ptr, len - fslen, "/%s", "unknown-fs"); D_RETURN_(TRUE); #else - if (statfs(filename, &stfs) < 0) - { - if (S_ISLNK(st->st_mode)) - { - char *lastslash; - - lastslash = strrchr(filename, '/'); - if (lastslash) - { - char old = *(lastslash+1); - - *(lastslash+1) = '\0'; - if (statfs(filename, &stfs) < 0) - { - *(lastslash+1) = old; - D_RETURN_(FALSE); - } + /* Okay, we have the basic file type. Now stat the filesystem, + look up the type and complete the file type string. */ - *(lastslash+1) = old; - broken_link = TRUE; - } - } - else - { - D_RETURN_(FALSE); - } + if (statfs(filename, &stfs) < 0) + { + snprintf(ptr, len - fslen, "/%s", "unknown-fs"); + D_RETURN_(TRUE); } # ifdef __FreeBSD__ @@ -1763,16 +1780,21 @@ if (!dad || !kid) D_RETURN; - if (!kid->prev) - /* Nothing to optimize */ - D_RETURN; - efsd_lock_get_write_access(magic_lock); + /* Do NOT move this test above the above line! */ + if (!kid->prev) + { + /* Nothing to optimize */ + efsd_lock_release_write_access(magic_lock); + D_RETURN; + } + if (kid == dad->last_kid) dad->last_kid = kid->prev; - kid->prev->next = kid->next; + if (kid->prev) + kid->prev->next = kid->next; if (kid->next) kid->next->prev = kid->prev; @@ -1799,7 +1821,7 @@ if ((f = fopen(filename, "r")) == NULL) D_RETURN_(FALSE); - if (filetype_magic_test_level(sys_magic.kids, f, s, TRUE, &match)) + if (filetype_magic_test_toplevel(sys_magic.kids, f, s, &match)) { int last; @@ -1816,7 +1838,7 @@ D_RETURN_(TRUE); } - if (filetype_magic_test_level(user_magic.kids, f, s, TRUE, &match)) + if (filetype_magic_test_toplevel(user_magic.kids, f, s, &match)) { int last; @@ -1916,7 +1938,7 @@ filetype_cache = efsd_hash_new(1023, 10, (EfsdHashFunc)efsd_hash_string, (EfsdCmpFunc)strcmp, - filetype_hash_item_free); + (EfsdFunc)filetype_hash_item_free); D_RETURN; } =================================================================== RCS file: /cvsroot/enlightenment/e17/apps/efsd/efsd/efsd_hash.c,v retrieving revision 1.14 retrieving revision 1.14.2.1 diff -u -3 -r1.14 -r1.14.2.1 --- efsd_hash.c 30 Sep 2001 18:35:07 -0000 1.14 +++ efsd_hash.c 15 Apr 2002 22:09:01 -0000 1.14.2.1 @@ -47,7 +47,7 @@ EfsdHashFunc hash_func; EfsdCmpFunc cmp_func; - EfsdHashItemFreeFunc free_func; + EfsdFunc free_func; }; @@ -60,8 +60,8 @@ EfsdHash * -efsd_hash_new(int num_buckets, int bucket_size, EfsdHashFunc hash_func, - EfsdCmpFunc cmp_func, EfsdHashItemFreeFunc free_func) +efsd_hash_new(int num_buckets, int bucket_size_max, EfsdHashFunc hash_func, + EfsdCmpFunc cmp_func, EfsdFunc free_func) { EfsdHash *h; @@ -71,7 +71,7 @@ memset(h, 0, sizeof(EfsdHash)); h->num_buckets = num_buckets; - h->max_bucket_size = bucket_size; + h->max_bucket_size = bucket_size_max; h->hash_func = hash_func; h->cmp_func = cmp_func; h->free_func = free_func; @@ -110,7 +110,7 @@ void -efsd_hash_free_with_func(EfsdHash *h, EfsdHashItemFreeFunc free_func) +efsd_hash_free_with_func(EfsdHash *h, EfsdFunc free_func) { D_ENTER; @@ -292,6 +292,30 @@ } +void * +efsd_hash_change_val(EfsdHash *h, void *key, void *data) +{ + void *old; + EfsdHashItem *it = NULL; + + D_ENTER; + + if (!h || !key) + D_RETURN_(NULL); + + if (! (it = efsd_hash_find(h, key))) + { + D("Item doesn't exist -- cannot change any content..\n"); + D_RETURN_(NULL); + } + + old = it->data; + it->data = data; + + D_RETURN_(old); +} + + int efsd_hash_num_buckets(EfsdHash *h) { @@ -318,6 +342,9 @@ D_ENTER; + if (!h) + D_RETURN_(0); + ss = s; for (hash = 0; *s != '\0'; s++) @@ -326,6 +353,40 @@ /* D("String '%s' hashed to %i\n", ss, hash); */ D_RETURN_(hash); +} + + +unsigned int +efsd_hash_int(EfsdHash *h, int data) +{ + unsigned int hash; + + D_ENTER; + + if (!h) + D_RETURN_(0); + + hash = data % h->num_buckets; + + D_RETURN_(hash); +} + + +int +efsd_hash_cmp_int(int *i1, int *i2) +{ + int result; + + D_ENTER; + + if (i1 == i2) + result = 0; + else if (i1 < i2) + result = -1; + else + result = 1; + + D_RETURN_(result); } =================================================================== RCS file: /cvsroot/enlightenment/e17/apps/efsd/efsd/efsd_hash.h,v retrieving revision 1.5 retrieving revision 1.5.2.1 diff -u -3 -r1.5 -r1.5.2.1 --- efsd_hash.h 23 Aug 2001 14:05:38 -0000 1.5 +++ efsd_hash.h 15 Apr 2002 22:09:01 -0000 1.5.2.1 @@ -39,14 +39,13 @@ typedef unsigned int (*EfsdHashFunc) (EfsdHash *h, void *data); typedef int (*EfsdCmpFunc) (void *d1, void *d2); -typedef void (*EfsdHashItemFreeFunc) (EfsdHashItem *it); -EfsdHash *efsd_hash_new(int num_buckets, int bucket_size, +EfsdHash *efsd_hash_new(int num_buckets, int bucket_size_max, EfsdHashFunc hash_func, EfsdCmpFunc cmp_func, - EfsdHashItemFreeFunc free_func); + EfsdFunc free_func); void efsd_hash_free(EfsdHash *h); -void efsd_hash_free_with_func(EfsdHash *h, EfsdHashItemFreeFunc free_func); +void efsd_hash_free_with_func(EfsdHash *h, EfsdFunc free_func); int efsd_hash_insert(EfsdHash *h, void *key, void *data); /* Returns NULL if item not found or the data of the @@ -55,11 +54,16 @@ void efsd_hash_remove(EfsdHash *h, void *key, EfsdFunc free_func); void efsd_hash_change_key(EfsdHash *h, void *key1, void *key2); +/* Replaces the content of a hash item, returning the old content. */ +void *efsd_hash_change_val(EfsdHash *h, void *key, void *data); + int efsd_hash_num_buckets(EfsdHash *h); int efsd_hash_max_bucket_size(EfsdHash *h); /* Standard hash functions: */ unsigned int efsd_hash_string(EfsdHash *h, char *data); +unsigned int efsd_hash_int(EfsdHash *h, int data); +int efsd_hash_cmp_int(int *i1, int *i2); /* Hash iterators -- iterates over all items that are stored inside a hash table */ =================================================================== RCS file: /cvsroot/enlightenment/e17/apps/efsd/efsd/efsd_main.c,v retrieving revision 1.52 retrieving revision 1.52.2.1 diff -u -3 -r1.52 -r1.52.2.1 --- efsd_main.c 6 Dec 2001 23:06:04 -0000 1.52 +++ efsd_main.c 15 Apr 2002 22:09:01 -0000 1.52.2.1 @@ -1076,14 +1076,14 @@ signal(SIGPIPE, SIG_IGN); signal(SIGQUIT, main_crash_sighandler); - signal(SIGSEGV, main_crash_sighandler); + /* signal(SIGSEGV, main_crash_sighandler); */ signal(SIGFPE, main_crash_sighandler); signal(SIGILL, main_crash_sighandler); #ifdef SIGSYS signal(SIGSYS, main_crash_sighandler); #endif atexit(efsd_misc_remove_socket_file); - efsd_misc_create_efsd_dir(); + efsd_misc_create_user_dir(); getcwd(app_cmd, MAXPATHLEN); sprintf(app_cmd + strlen(app_cmd), "/%s", appname); =================================================================== RCS file: /cvsroot/enlightenment/e17/apps/efsd/efsd/efsd_meta_monitor.c,v retrieving revision 1.2 retrieving revision 1.2.2.1 diff -u -3 -r1.2 -r1.2.2.1 --- efsd_meta_monitor.c 6 Dec 2001 23:06:04 -0000 1.2 +++ efsd_meta_monitor.c 15 Apr 2002 22:09:01 -0000 1.2.2.1 @@ -359,7 +359,7 @@ D_ENTER; meta_monitors = efsd_hash_new(1023, 10, (EfsdHashFunc)efsd_hash_string, - (EfsdCmpFunc)strcmp, meta_monitor_hash_item_free); + (EfsdCmpFunc)strcmp, (EfsdFunc)meta_monitor_hash_item_free); meta_monitors_lock = efsd_lock_new(); =================================================================== RCS file: /cvsroot/enlightenment/e17/apps/efsd/efsd/efsd_misc.c,v retrieving revision 1.35 retrieving revision 1.35.2.1 diff -u -3 -r1.35 -r1.35.2.1 --- efsd_misc.c 26 Nov 2001 01:06:38 -0000 1.35 +++ efsd_misc.c 15 Apr 2002 22:09:01 -0000 1.35.2.1 @@ -316,6 +316,9 @@ if (mkdir(filename, mode_755) < 0) { + if (errno == EEXIST && efsd_misc_file_is_dir(filename)) + D_RETURN_(TRUE); + D_RETURN_(FALSE); } @@ -491,36 +494,6 @@ } -void -efsd_misc_create_efsd_dir(void) -{ - struct passwd *pw = NULL; - char dir[MAXPATHLEN]; - char s[MAXPATHLEN]; - - D_ENTER; - - if ( (pw = getpwuid(geteuid()))) - { - snprintf(dir, MAXPATHLEN, "%s/.e", pw->pw_dir); - } - else - { - snprintf(dir, MAXPATHLEN, "/tmp/.efsd_%u", geteuid()); - } - - if (!efsd_misc_file_is_dir(dir)) - efsd_misc_mkdir(dir); - - snprintf(s, sizeof(s), "%s/efsd", dir); - - if (!efsd_misc_file_is_dir(s)) - efsd_misc_mkdir(s); - - D_RETURN; -} - - void efsd_misc_remove_socket_file(void) { @@ -545,39 +518,57 @@ char * efsd_misc_get_user_dir(void) { - char *dir = NULL; - static char s[MAXPATHLEN] = "\0"; - + struct passwd *pw = NULL; + static char s[MAXPATHLEN] = "\0"; + D_ENTER; if (s[0] != '\0') D_RETURN_(s); - dir = getenv("HOME"); + if ( (pw = getpwuid(geteuid()))) + { + snprintf(s, sizeof(s), "%s/.e/efsd", pw->pw_dir); + } + else + { + snprintf(s, MAXPATHLEN, "/tmp/.efsd_%u", geteuid()); + } - /* I'm not using getenv("TMPDIR") -- - * I don't see TMPDIR on Linux, FreeBSD - * or Solaris here... - */ + D_RETURN_(s); +} - /* FIXME -- I need to properly handle the case - where I cannot determine the home directory. - This will break if multiple users run E on the - same machine: - */ +int +efsd_misc_create_user_dir(void) +{ + struct passwd *pw = NULL; + char s[MAXPATHLEN] = "\0"; - if (!dir) + D_ENTER; + + if ( (pw = getpwuid(geteuid()))) { - D("WARNING -- NO HOME FOUND\n"); - dir = "/tmp"; + snprintf(s, sizeof(s), "%s/.e", pw->pw_dir); + if (efsd_misc_mkdir(s) < 0) + D_RETURN_(FALSE); + + snprintf(s, sizeof(s), "%s/.e/efsd", pw->pw_dir); + if (efsd_misc_mkdir(s) < 0) + D_RETURN_(FALSE); + } + else + { + snprintf(s, MAXPATHLEN, "/tmp/.efsd_%u", geteuid()); + if (efsd_misc_mkdir(s) < 0) + D_RETURN_(FALSE); } - snprintf(s, sizeof(s), "%s/.e/efsd", dir); - - D_RETURN_(s); + D_RETURN_(TRUE); } + + char * efsd_misc_get_sys_dir(void) { @@ -593,12 +584,15 @@ D_ENTER; + /* The socket file is always created in /tmp to avoid performance + issues when a home directory is mounted over a remote filesystem. */ + if (s[0] != '\0') D_RETURN_(s); #ifndef __EMX__ - snprintf(s, sizeof(s), "%s/efsd_socket", efsd_misc_get_user_dir()); + snprintf(s, sizeof(s), "/tmp/.efsd_socket_%u", geteuid()); #else - snprintf(s, sizeof(s), "\\socket\\%s/efsd_socket", efsd_misc_get_user_dir()); + snprintf(s, sizeof(s), "\\socket\\.efsd_socket_%u", geteuid()); #endif s[sizeof(s)-1] = '\0'; D_RETURN_(s); =================================================================== RCS file: /cvsroot/enlightenment/e17/apps/efsd/efsd/efsd_misc.h,v retrieving revision 1.23 retrieving revision 1.23.2.1 diff -u -3 -r1.23 -r1.23.2.1 --- efsd_misc.h 26 Nov 2001 01:06:38 -0000 1.23 +++ efsd_misc.h 15 Apr 2002 22:09:01 -0000 1.23.2.1 @@ -52,9 +52,10 @@ */ int efsd_misc_rename(char *file1, char *file2); -/* Simple mkdir wrapper. +/* Helper function to create directories. */ int efsd_misc_mkdir(char *filename); + void efsd_misc_remove_trailing_slashes(char *path); int efsd_misc_is_absolute_path(char *path); char *efsd_misc_get_filename_only(char *path); @@ -65,7 +66,7 @@ void efsd_slashify(char *path); #endif -void efsd_misc_create_efsd_dir(void); +int efsd_misc_create_user_dir(void); void efsd_misc_remove_socket_file(void); int efsd_misc_close_connection(int client); =================================================================== RCS file: /cvsroot/enlightenment/e17/apps/efsd/efsd/efsd_monitor.c,v retrieving revision 1.23 retrieving revision 1.23.2.1 diff -u -3 -r1.23 -r1.23.2.1 --- efsd_monitor.c 6 Dec 2001 23:06:04 -0000 1.23 +++ efsd_monitor.c 15 Apr 2002 22:09:01 -0000 1.23.2.1 @@ -599,7 +599,7 @@ } monitors = efsd_hash_new(1023, 10, (EfsdHashFunc)monitor_key_hash, - (EfsdCmpFunc)monitor_key_cmp, monitor_hash_item_free); + (EfsdCmpFunc)monitor_key_cmp, (EfsdFunc)monitor_hash_item_free); monitors_lock = efsd_lock_new(); =================================================================== RCS file: /cvsroot/enlightenment/e17/apps/efsd/efsd/efsd_statcache.c,v retrieving revision 1.18 retrieving revision 1.18.2.1 diff -u -3 -r1.18 -r1.18.2.1 --- efsd_statcache.c 6 Dec 2001 23:06:04 -0000 1.18 +++ efsd_statcache.c 15 Apr 2002 22:09:01 -0000 1.18.2.1 @@ -201,10 +201,10 @@ D_ENTER; stat_cache = efsd_hash_new(1023, 10, (EfsdHashFunc)efsd_hash_string, - (EfsdCmpFunc)strcmp, stat_hash_item_free); + (EfsdCmpFunc)strcmp, (EfsdFunc)stat_hash_item_free); lstat_cache = efsd_hash_new(1023, 10, (EfsdHashFunc)efsd_hash_string, - (EfsdCmpFunc)strcmp, stat_hash_item_free); + (EfsdCmpFunc)strcmp, (EfsdFunc)stat_hash_item_free); stat_lock = efsd_lock_new(); @@ -217,8 +217,8 @@ { D_ENTER; - efsd_hash_free_with_func(stat_cache, stat_hash_item_free_no_monitor_update); - efsd_hash_free_with_func(lstat_cache, stat_hash_item_free_no_monitor_update); + efsd_hash_free_with_func(stat_cache, (EfsdFunc)stat_hash_item_free_no_monitor_update); + efsd_hash_free_with_func(lstat_cache, (EfsdFunc)stat_hash_item_free_no_monitor_update); efsd_lock_free(stat_lock); stat_cache = NULL; =================================================================== RCS file: /cvsroot/enlightenment/e17/apps/efsd/efsd/libefsd.c,v retrieving revision 1.56 retrieving revision 1.56.2.1 diff -u -3 -r1.56 -r1.56.2.1 --- libefsd.c 21 Dec 2001 00:01:51 -0000 1.56 +++ libefsd.c 15 Apr 2002 22:09:01 -0000 1.56.2.1 @@ -51,6 +51,7 @@ #include <efsd_options.h> #include <efsd_types.h> #include <efsd_queue.h> +#include <efsd_hash.h> #include <libefsd_misc.h> #include <libefsd.h> @@ -74,6 +75,9 @@ }; +static EfsdHash *callbacks_hash = NULL; + + static char *libefsd_get_full_path(char *file); static int libefsd_send_command(EfsdConnection *ec, EfsdCommand *com); static EfsdCmdId libefsd_get_next_id(void); @@ -92,6 +96,8 @@ static void libefsd_cmd_queue_add_command(EfsdConnection *ec, EfsdCommand *com); static void libefsd_cmd_queue_process(EfsdConnection *ec); +static void libefsd_callbacks_init(void); + static char* libefsd_get_full_path(char *file) { @@ -345,6 +351,39 @@ } +static void +libefsd_hash_item_free(EfsdHashItem *it) +{ + D_ENTER; + + if (!it) + D_RETURN; + + FREE(it->key); + efsd_callbacks_cleanup((EfsdEventCallbacks*) it->data); + FREE(it); + + D_RETURN; +} + + +static void +libefsd_callbacks_init(void) +{ + D_ENTER; + + if (callbacks_hash) + D_RETURN; + + callbacks_hash = efsd_hash_new(1023, 100, (EfsdHashFunc)efsd_hash_int, + (EfsdCmpFunc)efsd_hash_cmp_int, + (EfsdFunc)libefsd_hash_item_free); + + D_RETURN; +} + + + /* Efsd API starts here --------------------------------------------- */ @@ -492,6 +531,119 @@ } +int +efsd_dispatch_event(EfsdEvent *ev) +{ + EfsdEventCallbacks *callbacks = NULL; + EfsdCmdId id = 0; + int handled = FALSE; + + D_ENTER; + + if (!ev) + D_RETURN_(-1); + + if ( (id = efsd_event_id(ev)) < 0) + D_RETURN_(-1); + + callbacks = + (EfsdEventCallbacks*) efsd_hash_find(callbacks_hash, (void*) id); + + if (!callbacks) + D_RETURN_(FALSE); + + switch (ev->type) + { + case EFSD_EVENT_FILECHANGE: + switch (ev->efsd_filechange_event.changetype) + { + case EFSD_FILE_CHANGED: + if (callbacks->changed_cb) + { + callbacks->changed_cb(&(ev->efsd_filechange_event)); + handled = TRUE; + } + break; + case EFSD_FILE_DELETED: + if (callbacks->delete_cb) + { + callbacks->delete_cb(&(ev->efsd_filechange_event)); + handled = TRUE; + } + break; + case EFSD_FILE_START_EXEC: + if (callbacks->startexec_cb) + { + callbacks->startexec_cb(&(ev->efsd_filechange_event)); + handled = TRUE; + } + break; + case EFSD_FILE_STOP_EXEC: + if (callbacks->stopexec_cb) + { + callbacks->stopexec_cb(&(ev->efsd_filechange_event)); + handled = TRUE; + } + break; + case EFSD_FILE_CREATED: + if (callbacks->created_cb) + { + callbacks->created_cb(&(ev->efsd_filechange_event)); + handled = TRUE; + } + break; + case EFSD_FILE_MOVED: + if (callbacks->moved_cb) + { + callbacks->moved_cb(&(ev->efsd_filechange_event)); + handled = TRUE; + } + break; + case EFSD_FILE_ACKNOWLEDGE: + if (callbacks->ack_cb) + { + callbacks->ack_cb(&(ev->efsd_filechange_event)); + handled = TRUE; + } + break; + case EFSD_FILE_EXISTS: + if (callbacks->exists_cb) + { + callbacks->exists_cb(&(ev->efsd_filechange_event)); + handled = TRUE; + } + break; + case EFSD_FILE_END_EXISTS: + if (callbacks->endexists_cb) + { + callbacks->endexists_cb(&(ev->efsd_filechange_event)); + handled = TRUE; + } + break; + default: + D_RETURN_(-1); + } + break; + case EFSD_EVENT_REPLY: + if (callbacks->reply_cb) + { + callbacks->reply_cb(&(ev->efsd_reply_event)); + } + break; + case EFSD_EVENT_METADATA_CHANGE: + if (callbacks->metadata_cb) + { + callbacks->metadata_cb(&(ev->efsd_metachange_event)); + } + break; + default: + D_RETURN_(-1); + } + + D_RETURN_(handled); +} + + int efsd_commands_pending(EfsdConnection *ec) { @@ -1317,3 +1469,61 @@ D_RETURN_(NULL); } + +EfsdEventCallbacks * +efsd_callbacks_create(void) +{ + EfsdEventCallbacks *cbs = NULL; + + D_ENTER; + + if (! (cbs = NEW(EfsdEventCallbacks))) + D_RETURN_(NULL); + + memset(cbs, 0, sizeof(EfsdEventCallbacks)); + + D_RETURN_(cbs); +} + + +void +efsd_callbacks_cleanup(EfsdEventCallbacks *callbacks) +{ + D_ENTER; + + FREE(callbacks); + + D_RETURN; +} + + +EfsdEventCallbacks * +efsd_callbacks_register(EfsdCmdId id, EfsdEventCallbacks *callbacks) +{ + EfsdEventCallbacks *old_callbacks = NULL; + + D_ENTER; + + /* Make sure the hashtable is initialized ... */ + libefsd_callbacks_init(); + + /* Try to change the value. If old_callbacks is NULL, it didn't work. */ + old_callbacks = efsd_hash_change_val(callbacks_hash, (void*) id, + (void*) callbacks); + + /* If callbacks is NULL, the user wants to remove the callbacks: */ + if (!callbacks) + efsd_hash_remove(callbacks_hash, (void*) id, NULL); + + /* If we got old callbacks, return them. */ + if (old_callbacks) + { + D_RETURN_(old_callbacks); + } + else /* otherwise, this is a new insertion for this id. */ + { + efsd_hash_insert(callbacks_hash, (void*) id, (void*) callbacks); + } + + D_RETURN_(NULL); +} =================================================================== RCS file: /cvsroot/enlightenment/e17/apps/efsd/efsd/libefsd.h,v retrieving revision 1.44 retrieving revision 1.44.2.1 diff -u -3 -r1.44 -r1.44.2.1 --- libefsd.h 26 Nov 2001 01:06:38 -0000 1.44 +++ libefsd.h 15 Apr 2002 22:09:01 -0000 1.44.2.1 @@ -44,6 +44,34 @@ typedef struct efsd_connection EfsdConnection; typedef struct efsd_options EfsdOptions; + +/* Function prototype typedefs for the various file change + event handlers: */ + +typedef void (*EfsdFileEventFunc) (EfsdFileChangeEvent *ev); +typedef void (*EfsdFileMetadataEventFunc) (EfsdMetadataChangeEvent *ev); +typedef void (*EfsdReplyFunc) (EfsdReplyEvent *ev); + +/* And a struct that puts them all together. Look at the + efsd_callbacks_... functions */ +typedef struct efsd_event_callbacks +{ + EfsdFileEventFunc changed_cb; + EfsdFileEventFunc delete_cb; + EfsdFileEventFunc startexec_cb; + EfsdFileEventFunc stopexec_cb; + EfsdFileEventFunc created_cb; + EfsdFileEventFunc moved_cb; + EfsdFileEventFunc ack_cb; + EfsdFileEventFunc exists_cb; + EfsdFileEventFunc endexists_cb; + EfsdFileMetadataEventFunc metadata_cb; + EfsdReplyFunc reply_cb; +} +EfsdEventCallbacks; + + + /** * efsd_open - Creates and returns an efsd connection. * @@ -101,6 +129,21 @@ int efsd_next_event(EfsdConnection *ec, EfsdEvent *ev); +/** + * efsd_dispatch_event - handles events through the dispatching mechanism. + * @ev: The Efsd event to dispatch. + * + * This function looks up the set of callbacks for the command ID contained + * in the event, and then dispatches this event to the appropriate callback. + * If no set of callbacks is found or the matching callback isn't defined + * in the EfsdEventCallbacks struct, nothing happens. + * + * Returns -1 when an error occurs, FALSE when the event didn't get + * dispatched, and TRUE when it got dispatched. + */ +int efsd_dispatch_event(EfsdEvent *ev); + + /** * efsd_wait_event - blocking wait for next Efsd event. * @ec: The Efsd connection @@ -697,6 +740,39 @@ * %EFSD_FILE_EXISTS also for hidden files (starting with a '.'). */ EfsdOption *efsd_op_list_all(void); + + + +/** + * efsd_callbacks_create - returns an initialized event callback struct. + * + */ +EfsdEventCallbacks *efsd_callbacks_create(void); + +/** + * efsd_callbacks_cleanup - cleans up memory occupied by a callbacks struct. + * @callbacks: callbacks structure to clean up. + */ +void efsd_callbacks_cleanup(EfsdEventCallbacks *callbacks); + + +/** + * efsd_callbacks_register - registers a set of handlers for a particular monitor. + * @id: Command ID of the monitoring request. + * @callbacks: Initialized callback set. + * + * You can register a set of event handlers for a particular file monitor + * here. Pass the command ID that was returned by the corresponding + * monitor request call as first argument, and an EfsdEventCallback struct + * that is initialized properly second. You don't need to initialize + * callbacks you don't want to use. + * + * If you want to change the set of callbacks for an ID, just call this + * function again, you'll get the old set in return (and NULL otherwise). + * Similarly, if you want to remove a callback set for a command ID, just + * pass NULL as the second argument. + */ +EfsdEventCallbacks *efsd_callbacks_register(EfsdCmdId id, EfsdEventCallbacks *callbacks); #ifdef __cplusplus } =================================================================== RCS file: /cvsroot/enlightenment/e17/apps/efsd/efsd/libefsd_misc.c,v retrieving revision 1.4 retrieving revision 1.4.2.1 diff -u -3 -r1.4 -r1.4.2.1 --- libefsd_misc.c 26 Nov 2001 01:06:38 -0000 1.4 +++ libefsd_misc.c 15 Apr 2002 22:09:01 -0000 1.4.2.1 @@ -128,9 +128,9 @@ if (s[0] != '\0') D_RETURN_(s); #ifndef __EMX__ - snprintf(s, sizeof(s), "%s/efsd_socket", misc_get_user_dir()); + snprintf(s, sizeof(s), "/tmp/.efsd_socket_%u", geteuid()); #else - snprintf(s, sizeof(s), "\\socket\\%s/efsd_socket", misc_get_user_dir()); + snprintf(s, sizeof(s), "\\socket\\.efsd_socket_%u", geteuid()); #endif s[sizeof(s)-1] = '\0'; D_RETURN_(s); |
From: <enl...@li...> - 2002-04-15 22:09:33
|
Enlightenment CVS committal Author : cpk Project : e17 Module : apps/efsd Dir : e17/apps/efsd Modified Files: Tag: SPLIT TODO Log Message: AAAAAAAAHHH new code :) * Fixed reporting of dead links -- a dangling symlink is correctly reported as dead-link/unknown-fs again. Seems I broke that a while ago. * Prefixed the inclusion path for the libxml2 headers with "libxml" to fix the issues reported by Alan. * Fixed a race condition in the filetype move-to-front heuristic: under high load it was possible that a matching magic description got moved to the front of the list while other checks where iterating over the list already, the matching filetype was thus not found. * efsd_misc_get_user_dir() also uses getpwuid to find out the home dir. * Moved the socket file to /tmp to avoid issues with nfs-mounted homes, as Raster had pointed out. * Added an event callback interface to libefsd to be able to register handlers instead of having to use switch-case statements. Added management code to libefsd to make these handlers per-monitor. This is completely untested yet and will probably blow up right into your face :) * Fixed a bug in efsdsh, -ls actually performs an lstat() now. =================================================================== RCS file: /cvsroot/enlightenment/e17/apps/efsd/TODO,v retrieving revision 1.9 retrieving revision 1.9.2.1 diff -u -3 -r1.9 -r1.9.2.1 --- TODO 22 Feb 2002 12:04:09 -0000 1.9 +++ TODO 15 Apr 2002 22:09:00 -0000 1.9.2.1 @@ -8,21 +8,10 @@ * implement a comprehensive test suite. -* File types have a bug that under some circumstances - produce the result document/unknown instead of the - correct one. Bug in the MF heuristic? - * Issues with monitoring of single files? imon? Test dnotify. -* Update efsd_misc_get_user_dir() to also use getpwuid() - instead of getenv("HOME"). - -* Move socket file to /tmp to avoid problems when - home is nfs-shared. - * Unmounting of e.g. cdroms not working because Efsd - keeps monitors around? + keeps monitors around? I currently cannot reproduce this. -* Add event callbacks to libefsd to be able to register - handlers instead of having to use switch-case statements. +* Add a C++ wrapper library around libefsd. |
From: <enl...@li...> - 2002-04-15 22:09:03
|
Enlightenment CVS committal Author : cpk Project : e17 Module : apps/efsd Dir : e17/apps/efsd/tools Modified Files: Tag: SPLIT efsdsh.c Log Message: AAAAAAAAHHH new code :) * Fixed reporting of dead links -- a dangling symlink is correctly reported as dead-link/unknown-fs again. Seems I broke that a while ago. * Prefixed the inclusion path for the libxml2 headers with "libxml" to fix the issues reported by Alan. * Fixed a race condition in the filetype move-to-front heuristic: under high load it was possible that a matching magic description got moved to the front of the list while other checks where iterating over the list already, the matching filetype was thus not found. * efsd_misc_get_user_dir() also uses getpwuid to find out the home dir. * Moved the socket file to /tmp to avoid issues with nfs-mounted homes, as Raster had pointed out. * Added an event callback interface to libefsd to be able to register handlers instead of having to use switch-case statements. Added management code to libefsd to make these handlers per-monitor. This is completely untested yet and will probably blow up right into your face :) * Fixed a bug in efsdsh, -ls actually performs an lstat() now. =================================================================== RCS file: /cvsroot/enlightenment/e17/apps/efsd/tools/efsdsh.c,v retrieving revision 1.21 retrieving revision 1.21.2.1 diff -u -3 -r1.21 -r1.21.2.1 --- efsdsh.c 26 Nov 2001 01:06:38 -0000 1.21 +++ efsdsh.c 15 Apr 2002 22:09:01 -0000 1.21.2.1 @@ -626,7 +626,7 @@ else if (!strcmp(tok, "-ls")) { num_options++; - get_stat = 1; + get_lstat = 1; } else if (!strcmp(tok, "-t")) { |
From: <enl...@li...> - 2002-05-14 09:46:49
|
Enlightenment CVS committal Author : cpk Project : e17 Module : apps/efsd Dir : e17/apps/efsd Modified Files: TODO Log Message: Updating HEAD to SPLIT's state... =================================================================== RCS file: /cvsroot/enlightenment/e17/apps/efsd/TODO,v retrieving revision 1.9 retrieving revision 1.10 diff -u -3 -r1.9 -r1.10 --- TODO 22 Feb 2002 12:04:09 -0000 1.9 +++ TODO 14 May 2002 09:46:17 -0000 1.10 @@ -8,21 +8,10 @@ * implement a comprehensive test suite. -* File types have a bug that under some circumstances - produce the result document/unknown instead of the - correct one. Bug in the MF heuristic? - * Issues with monitoring of single files? imon? Test dnotify. -* Update efsd_misc_get_user_dir() to also use getpwuid() - instead of getenv("HOME"). - -* Move socket file to /tmp to avoid problems when - home is nfs-shared. - * Unmounting of e.g. cdroms not working because Efsd - keeps monitors around? + keeps monitors around? I currently cannot reproduce this. -* Add event callbacks to libefsd to be able to register - handlers instead of having to use switch-case statements. +* Add a C++ wrapper library around libefsd. |
From: <enl...@li...> - 2002-05-14 09:46:49
|
Enlightenment CVS committal Author : cpk Project : e17 Module : apps/efsd Dir : e17/apps/efsd/tools Modified Files: efsdsh.c filetypes.xml Log Message: Updating HEAD to SPLIT's state... =================================================================== RCS file: /cvsroot/enlightenment/e17/apps/efsd/tools/efsdsh.c,v retrieving revision 1.21 retrieving revision 1.22 diff -u -3 -r1.21 -r1.22 --- efsdsh.c 26 Nov 2001 01:06:38 -0000 1.21 +++ efsdsh.c 14 May 2002 09:46:18 -0000 1.22 @@ -626,7 +626,7 @@ else if (!strcmp(tok, "-ls")) { num_options++; - get_stat = 1; + get_lstat = 1; } else if (!strcmp(tok, "-t")) { =================================================================== RCS file: /cvsroot/enlightenment/e17/apps/efsd/tools/filetypes.xml,v retrieving revision 1.3 retrieving revision 1.4 diff -u -3 -r1.3 -r1.4 --- filetypes.xml 23 Oct 2001 21:43:42 -0000 1.3 +++ filetypes.xml 14 May 2002 09:46:18 -0000 1.4 @@ -4874,32 +4874,7 @@ </mtest> <mtest data="string" byteorder="host" type="eq" id="950"> <offset>0</offset> - <magic>\0x00\0x00\0x01\0x00\0x01\0x00 \0x10\0x00\0x00\0x00\0x00\0x00\0xe8\0x02\0x00\0x00</magic> - <descr>image/ms-windows-icon/</descr> - </mtest> - <mtest data="string" byteorder="host" type="eq" id="951"> - <offset>0</offset> - <magic>\0x00\0x00\0x01\0x00\0x04\0x00 \0x10\0x00\0x00\0x00\0x00\0x00\0xe8\0x02</magic> - <descr>image/ms-windows-icon/</descr> - </mtest> - <mtest data="string" byteorder="host" type="eq" id="952"> - <offset>0</offset> - <magic>BA(\0x00\0x00\0x00.\0x00\0x00\0x00\0x00\0x00\0x00\0x00</magic> - <descr>image/ms-windows-icon/</descr> - </mtest> - <mtest data="string" byteorder="host" type="eq" id="953"> - <offset>0</offset> - <magic>\0x00\0x00\0x01\0x00\0x02\0x00 \0x08\0x00\0x00\0x00\0x00\0x00\0xe8\0x02</magic> - <descr>image/ms-windows-icon/</descr> - </mtest> - <mtest data="string" byteorder="host" type="eq" id="954"> - <offset>0</offset> - <magic>\0x00\0x00\0x01\0x00\0x06\0x00\0x10\0x10\0x10\0x00\0x00\0x00\0x00\0x00(\0x01</magic> - <descr>image/ms-windows-icon/</descr> - </mtest> - <mtest data="string" byteorder="host" type="eq" id="955"> - <offset>0</offset> - <magic>\0x00\0x00\0x01\0x00\0x02\0x00\0x10\0x10\0x10\0x00\0x00\0x00\0x00\0x00(\0x01</magic> + <magic>\0x00\0x00\0x01\0x00</magic> <descr>image/ms-windows-icon/</descr> </mtest> <mtest data="byte" byteorder="host" type="eq" id="956"> |
From: <enl...@li...> - 2002-05-14 09:46:49
|
Enlightenment CVS committal Author : cpk Project : e17 Module : apps/efsd Dir : e17/apps/efsd/efsd Modified Files: Makefile.am efsd_filetype.c efsd_fs.c efsd_hash.c efsd_hash.h efsd_main.c efsd_meta_monitor.c efsd_misc.c efsd_misc.h efsd_monitor.c efsd_statcache.c libefsd.c libefsd.h libefsd_misc.c Log Message: Updating HEAD to SPLIT's state... =================================================================== RCS file: /cvsroot/enlightenment/e17/apps/efsd/efsd/Makefile.am,v retrieving revision 1.28 retrieving revision 1.29 diff -u -3 -r1.28 -r1.29 --- Makefile.am 26 Nov 2001 01:06:38 -0000 1.28 +++ Makefile.am 14 May 2002 09:46:17 -0000 1.29 @@ -57,6 +57,7 @@ efsd_types.h efsd_types.c \ efsd_queue.h libefsd_queue.c \ efsd_list.h efsd_list.c \ + efsd_hash.h efsd_hash.c \ libefsd_misc.h libefsd_misc.c \ libefsd.c =================================================================== RCS file: /cvsroot/enlightenment/e17/apps/efsd/efsd/efsd_filetype.c,v retrieving revision 1.34 retrieving revision 1.35 diff -u -3 -r1.34 -r1.35 --- efsd_filetype.c 26 Nov 2001 01:06:38 -0000 1.34 +++ efsd_filetype.c 14 May 2002 09:46:17 -0000 1.35 @@ -49,20 +49,13 @@ #include <fnmatch.h> /* libxml stuff */ -#include <tree.h> -#include <parser.h> +#include <libxml/tree.h> +#include <libxml/parser.h> #ifdef __EMX__ #include <strings.h> #endif -#ifdef DEBUG -#undef DEBUG -#endif - -#ifdef DEBUG_NEST -#undef DEBUG_NEST -#endif #include <efsd.h> #include <efsd_debug.h> @@ -198,6 +191,9 @@ */ static EfsdMagic sys_magic; static EfsdMagic user_magic; + +/* Mhmm well ideally there should be separate locking for + user magic and system-wide magic ... */ static EfsdLock *magic_lock; /* Filename patterns */ @@ -251,6 +247,8 @@ static void filetype_magic_add_child(EfsdMagic *em_dad, EfsdMagic *em_kid); static void filetype_magic_move_match_to_front(EfsdMagic *dad, EfsdMagic *kid); +static char *filetype_magic_test_toplevel(EfsdMagic *em, FILE *f, + char *ptr, EfsdMagic **matching_kid); static char *filetype_magic_test_level(EfsdMagic *em, FILE *f, char *ptr, char stop_when_found, EfsdMagic **matching_kid); @@ -1341,6 +1339,25 @@ } +/* This is a wrapper call to filetype_magic_test_level() that + is intended for calls to the root level of the magic tree + structure. It protects access to the tree through readlocks. +*/ +static char * +filetype_magic_test_toplevel(EfsdMagic *level, FILE *f, + char *ptr, EfsdMagic **matching_kid) +{ + char *result = NULL; + + D_ENTER; + + efsd_lock_get_read_access(magic_lock); + result = filetype_magic_test_level(level, f, ptr, TRUE, matching_kid); + efsd_lock_release_read_access(magic_lock); + + D_RETURN_(result); +} + static char * filetype_magic_test_level(EfsdMagic *level, FILE *f, char *ptr, char stop_when_found, @@ -1588,9 +1605,28 @@ if (!st) D_RETURN_(FALSE); + /* First, determine the basic file type, and if it's a link, check + whether it's dead or not. Then, look up the type of the fs that + the file lives on. The result is something like "dir/ext2". + */ if (S_ISLNK(st->st_mode)) { + char real[MAXPATHLEN]; + int real_len = 0; + + if ( (real_len = readlink(filename, real, real_len) >= 0)) + { + real[real_len] = '\0'; + + if (!efsd_misc_file_exists(real)) + broken_link = TRUE; + } + else + { + broken_link = TRUE; + } + if (broken_link) snprintf(type, len, "%s", "broken-link"); else @@ -1634,33 +1670,14 @@ snprintf(ptr, len - fslen, "/%s", "unknown-fs"); D_RETURN_(TRUE); #else - if (statfs(filename, &stfs) < 0) - { - if (S_ISLNK(st->st_mode)) - { - char *lastslash; - - lastslash = strrchr(filename, '/'); - if (lastslash) - { - char old = *(lastslash+1); - - *(lastslash+1) = '\0'; - if (statfs(filename, &stfs) < 0) - { - *(lastslash+1) = old; - D_RETURN_(FALSE); - } + /* Okay, we have the basic file type. Now stat the filesystem, + look up the type and complete the file type string. */ - *(lastslash+1) = old; - broken_link = TRUE; - } - } - else - { - D_RETURN_(FALSE); - } + if (statfs(filename, &stfs) < 0) + { + snprintf(ptr, len - fslen, "/%s", "unknown-fs"); + D_RETURN_(TRUE); } # ifdef __FreeBSD__ @@ -1763,16 +1780,21 @@ if (!dad || !kid) D_RETURN; - if (!kid->prev) - /* Nothing to optimize */ - D_RETURN; - efsd_lock_get_write_access(magic_lock); + /* Do NOT move this test above the above line! */ + if (!kid->prev) + { + /* Nothing to optimize */ + efsd_lock_release_write_access(magic_lock); + D_RETURN; + } + if (kid == dad->last_kid) dad->last_kid = kid->prev; - kid->prev->next = kid->next; + if (kid->prev) + kid->prev->next = kid->next; if (kid->next) kid->next->prev = kid->prev; @@ -1799,7 +1821,7 @@ if ((f = fopen(filename, "r")) == NULL) D_RETURN_(FALSE); - if (filetype_magic_test_level(sys_magic.kids, f, s, TRUE, &match)) + if (filetype_magic_test_toplevel(sys_magic.kids, f, s, &match)) { int last; @@ -1816,7 +1838,7 @@ D_RETURN_(TRUE); } - if (filetype_magic_test_level(user_magic.kids, f, s, TRUE, &match)) + if (filetype_magic_test_toplevel(user_magic.kids, f, s, &match)) { int last; @@ -1916,7 +1938,7 @@ filetype_cache = efsd_hash_new(1023, 10, (EfsdHashFunc)efsd_hash_string, (EfsdCmpFunc)strcmp, - filetype_hash_item_free); + (EfsdFunc)filetype_hash_item_free); D_RETURN; } =================================================================== RCS file: /cvsroot/enlightenment/e17/apps/efsd/efsd/efsd_fs.c,v retrieving revision 1.13 retrieving revision 1.14 diff -u -3 -r1.13 -r1.14 --- efsd_fs.c 6 Dec 2001 23:06:04 -0000 1.13 +++ efsd_fs.c 14 May 2002 09:46:18 -0000 1.14 @@ -320,6 +320,7 @@ struct stat dst_st; DIR *dir; struct dirent de, *de_ptr; + int success = FALSE; D_ENTER; D("Copying directory %s to %s\n", src_path, dst_path); @@ -371,14 +372,14 @@ continue; if (S_ISDIR(src_st2.st_mode)) - dir_copy(src, &src_st2, dst); + success = dir_copy(src, &src_st2, dst); else - file_copy(src, &src_st2, dst); + success = file_copy(src, &src_st2, dst); } closedir(dir); - D_RETURN_(TRUE); + D_RETURN_(success); } =================================================================== RCS file: /cvsroot/enlightenment/e17/apps/efsd/efsd/efsd_hash.c,v retrieving revision 1.14 retrieving revision 1.15 diff -u -3 -r1.14 -r1.15 --- efsd_hash.c 30 Sep 2001 18:35:07 -0000 1.14 +++ efsd_hash.c 14 May 2002 09:46:18 -0000 1.15 @@ -47,7 +47,7 @@ EfsdHashFunc hash_func; EfsdCmpFunc cmp_func; - EfsdHashItemFreeFunc free_func; + EfsdFunc free_func; }; @@ -60,8 +60,8 @@ EfsdHash * -efsd_hash_new(int num_buckets, int bucket_size, EfsdHashFunc hash_func, - EfsdCmpFunc cmp_func, EfsdHashItemFreeFunc free_func) +efsd_hash_new(int num_buckets, int bucket_size_max, EfsdHashFunc hash_func, + EfsdCmpFunc cmp_func, EfsdFunc free_func) { EfsdHash *h; @@ -71,7 +71,7 @@ memset(h, 0, sizeof(EfsdHash)); h->num_buckets = num_buckets; - h->max_bucket_size = bucket_size; + h->max_bucket_size = bucket_size_max; h->hash_func = hash_func; h->cmp_func = cmp_func; h->free_func = free_func; @@ -110,7 +110,7 @@ void -efsd_hash_free_with_func(EfsdHash *h, EfsdHashItemFreeFunc free_func) +efsd_hash_free_with_func(EfsdHash *h, EfsdFunc free_func) { D_ENTER; @@ -292,6 +292,30 @@ } +void * +efsd_hash_change_val(EfsdHash *h, void *key, void *data) +{ + void *old; + EfsdHashItem *it = NULL; + + D_ENTER; + + if (!h || !key) + D_RETURN_(NULL); + + if (! (it = efsd_hash_find(h, key))) + { + D("Item doesn't exist -- cannot change any content..\n"); + D_RETURN_(NULL); + } + + old = it->data; + it->data = data; + + D_RETURN_(old); +} + + int efsd_hash_num_buckets(EfsdHash *h) { @@ -318,6 +342,9 @@ D_ENTER; + if (!h) + D_RETURN_(0); + ss = s; for (hash = 0; *s != '\0'; s++) @@ -326,6 +353,40 @@ /* D("String '%s' hashed to %i\n", ss, hash); */ D_RETURN_(hash); +} + + +unsigned int +efsd_hash_int(EfsdHash *h, int data) +{ + unsigned int hash; + + D_ENTER; + + if (!h) + D_RETURN_(0); + + hash = data % h->num_buckets; + + D_RETURN_(hash); +} + + +int +efsd_hash_cmp_int(int *i1, int *i2) +{ + int result; + + D_ENTER; + + if (i1 == i2) + result = 0; + else if (i1 < i2) + result = -1; + else + result = 1; + + D_RETURN_(result); } =================================================================== RCS file: /cvsroot/enlightenment/e17/apps/efsd/efsd/efsd_hash.h,v retrieving revision 1.5 retrieving revision 1.6 diff -u -3 -r1.5 -r1.6 --- efsd_hash.h 23 Aug 2001 14:05:38 -0000 1.5 +++ efsd_hash.h 14 May 2002 09:46:18 -0000 1.6 @@ -39,14 +39,13 @@ typedef unsigned int (*EfsdHashFunc) (EfsdHash *h, void *data); typedef int (*EfsdCmpFunc) (void *d1, void *d2); -typedef void (*EfsdHashItemFreeFunc) (EfsdHashItem *it); -EfsdHash *efsd_hash_new(int num_buckets, int bucket_size, +EfsdHash *efsd_hash_new(int num_buckets, int bucket_size_max, EfsdHashFunc hash_func, EfsdCmpFunc cmp_func, - EfsdHashItemFreeFunc free_func); + EfsdFunc free_func); void efsd_hash_free(EfsdHash *h); -void efsd_hash_free_with_func(EfsdHash *h, EfsdHashItemFreeFunc free_func); +void efsd_hash_free_with_func(EfsdHash *h, EfsdFunc free_func); int efsd_hash_insert(EfsdHash *h, void *key, void *data); /* Returns NULL if item not found or the data of the @@ -55,11 +54,16 @@ void efsd_hash_remove(EfsdHash *h, void *key, EfsdFunc free_func); void efsd_hash_change_key(EfsdHash *h, void *key1, void *key2); +/* Replaces the content of a hash item, returning the old content. */ +void *efsd_hash_change_val(EfsdHash *h, void *key, void *data); + int efsd_hash_num_buckets(EfsdHash *h); int efsd_hash_max_bucket_size(EfsdHash *h); /* Standard hash functions: */ unsigned int efsd_hash_string(EfsdHash *h, char *data); +unsigned int efsd_hash_int(EfsdHash *h, int data); +int efsd_hash_cmp_int(int *i1, int *i2); /* Hash iterators -- iterates over all items that are stored inside a hash table */ =================================================================== RCS file: /cvsroot/enlightenment/e17/apps/efsd/efsd/efsd_main.c,v retrieving revision 1.52 retrieving revision 1.53 diff -u -3 -r1.52 -r1.53 --- efsd_main.c 6 Dec 2001 23:06:04 -0000 1.52 +++ efsd_main.c 14 May 2002 09:46:18 -0000 1.53 @@ -1076,14 +1076,14 @@ signal(SIGPIPE, SIG_IGN); signal(SIGQUIT, main_crash_sighandler); - signal(SIGSEGV, main_crash_sighandler); + /* signal(SIGSEGV, main_crash_sighandler); */ signal(SIGFPE, main_crash_sighandler); signal(SIGILL, main_crash_sighandler); #ifdef SIGSYS signal(SIGSYS, main_crash_sighandler); #endif atexit(efsd_misc_remove_socket_file); - efsd_misc_create_efsd_dir(); + efsd_misc_create_user_dir(); getcwd(app_cmd, MAXPATHLEN); sprintf(app_cmd + strlen(app_cmd), "/%s", appname); =================================================================== RCS file: /cvsroot/enlightenment/e17/apps/efsd/efsd/efsd_meta_monitor.c,v retrieving revision 1.2 retrieving revision 1.3 diff -u -3 -r1.2 -r1.3 --- efsd_meta_monitor.c 6 Dec 2001 23:06:04 -0000 1.2 +++ efsd_meta_monitor.c 14 May 2002 09:46:18 -0000 1.3 @@ -359,7 +359,7 @@ D_ENTER; meta_monitors = efsd_hash_new(1023, 10, (EfsdHashFunc)efsd_hash_string, - (EfsdCmpFunc)strcmp, meta_monitor_hash_item_free); + (EfsdCmpFunc)strcmp, (EfsdFunc)meta_monitor_hash_item_free); meta_monitors_lock = efsd_lock_new(); =================================================================== RCS file: /cvsroot/enlightenment/e17/apps/efsd/efsd/efsd_misc.c,v retrieving revision 1.35 retrieving revision 1.36 diff -u -3 -r1.35 -r1.36 --- efsd_misc.c 26 Nov 2001 01:06:38 -0000 1.35 +++ efsd_misc.c 14 May 2002 09:46:18 -0000 1.36 @@ -316,6 +316,9 @@ if (mkdir(filename, mode_755) < 0) { + if (errno == EEXIST && efsd_misc_file_is_dir(filename)) + D_RETURN_(TRUE); + D_RETURN_(FALSE); } @@ -491,36 +494,6 @@ } -void -efsd_misc_create_efsd_dir(void) -{ - struct passwd *pw = NULL; - char dir[MAXPATHLEN]; - char s[MAXPATHLEN]; - - D_ENTER; - - if ( (pw = getpwuid(geteuid()))) - { - snprintf(dir, MAXPATHLEN, "%s/.e", pw->pw_dir); - } - else - { - snprintf(dir, MAXPATHLEN, "/tmp/.efsd_%u", geteuid()); - } - - if (!efsd_misc_file_is_dir(dir)) - efsd_misc_mkdir(dir); - - snprintf(s, sizeof(s), "%s/efsd", dir); - - if (!efsd_misc_file_is_dir(s)) - efsd_misc_mkdir(s); - - D_RETURN; -} - - void efsd_misc_remove_socket_file(void) { @@ -545,39 +518,57 @@ char * efsd_misc_get_user_dir(void) { - char *dir = NULL; - static char s[MAXPATHLEN] = "\0"; - + struct passwd *pw = NULL; + static char s[MAXPATHLEN] = "\0"; + D_ENTER; if (s[0] != '\0') D_RETURN_(s); - dir = getenv("HOME"); + if ( (pw = getpwuid(geteuid()))) + { + snprintf(s, sizeof(s), "%s/.e/efsd", pw->pw_dir); + } + else + { + snprintf(s, MAXPATHLEN, "/tmp/.efsd_%u", geteuid()); + } - /* I'm not using getenv("TMPDIR") -- - * I don't see TMPDIR on Linux, FreeBSD - * or Solaris here... - */ + D_RETURN_(s); +} - /* FIXME -- I need to properly handle the case - where I cannot determine the home directory. - This will break if multiple users run E on the - same machine: - */ +int +efsd_misc_create_user_dir(void) +{ + struct passwd *pw = NULL; + char s[MAXPATHLEN] = "\0"; - if (!dir) + D_ENTER; + + if ( (pw = getpwuid(geteuid()))) { - D("WARNING -- NO HOME FOUND\n"); - dir = "/tmp"; + snprintf(s, sizeof(s), "%s/.e", pw->pw_dir); + if (efsd_misc_mkdir(s) < 0) + D_RETURN_(FALSE); + + snprintf(s, sizeof(s), "%s/.e/efsd", pw->pw_dir); + if (efsd_misc_mkdir(s) < 0) + D_RETURN_(FALSE); + } + else + { + snprintf(s, MAXPATHLEN, "/tmp/.efsd_%u", geteuid()); + if (efsd_misc_mkdir(s) < 0) + D_RETURN_(FALSE); } - snprintf(s, sizeof(s), "%s/.e/efsd", dir); - - D_RETURN_(s); + D_RETURN_(TRUE); } + + char * efsd_misc_get_sys_dir(void) { @@ -593,12 +584,15 @@ D_ENTER; + /* The socket file is always created in /tmp to avoid performance + issues when a home directory is mounted over a remote filesystem. */ + if (s[0] != '\0') D_RETURN_(s); #ifndef __EMX__ - snprintf(s, sizeof(s), "%s/efsd_socket", efsd_misc_get_user_dir()); + snprintf(s, sizeof(s), "/tmp/.efsd_socket_%u", geteuid()); #else - snprintf(s, sizeof(s), "\\socket\\%s/efsd_socket", efsd_misc_get_user_dir()); + snprintf(s, sizeof(s), "\\socket\\.efsd_socket_%u", geteuid()); #endif s[sizeof(s)-1] = '\0'; D_RETURN_(s); =================================================================== RCS file: /cvsroot/enlightenment/e17/apps/efsd/efsd/efsd_misc.h,v retrieving revision 1.23 retrieving revision 1.24 diff -u -3 -r1.23 -r1.24 --- efsd_misc.h 26 Nov 2001 01:06:38 -0000 1.23 +++ efsd_misc.h 14 May 2002 09:46:18 -0000 1.24 @@ -52,9 +52,10 @@ */ int efsd_misc_rename(char *file1, char *file2); -/* Simple mkdir wrapper. +/* Helper function to create directories. */ int efsd_misc_mkdir(char *filename); + void efsd_misc_remove_trailing_slashes(char *path); int efsd_misc_is_absolute_path(char *path); char *efsd_misc_get_filename_only(char *path); @@ -65,7 +66,7 @@ void efsd_slashify(char *path); #endif -void efsd_misc_create_efsd_dir(void); +int efsd_misc_create_user_dir(void); void efsd_misc_remove_socket_file(void); int efsd_misc_close_connection(int client); =================================================================== RCS file: /cvsroot/enlightenment/e17/apps/efsd/efsd/efsd_monitor.c,v retrieving revision 1.23 retrieving revision 1.24 diff -u -3 -r1.23 -r1.24 --- efsd_monitor.c 6 Dec 2001 23:06:04 -0000 1.23 +++ efsd_monitor.c 14 May 2002 09:46:18 -0000 1.24 @@ -599,7 +599,7 @@ } monitors = efsd_hash_new(1023, 10, (EfsdHashFunc)monitor_key_hash, - (EfsdCmpFunc)monitor_key_cmp, monitor_hash_item_free); + (EfsdCmpFunc)monitor_key_cmp, (EfsdFunc)monitor_hash_item_free); monitors_lock = efsd_lock_new(); =================================================================== RCS file: /cvsroot/enlightenment/e17/apps/efsd/efsd/efsd_statcache.c,v retrieving revision 1.18 retrieving revision 1.19 diff -u -3 -r1.18 -r1.19 --- efsd_statcache.c 6 Dec 2001 23:06:04 -0000 1.18 +++ efsd_statcache.c 14 May 2002 09:46:18 -0000 1.19 @@ -201,10 +201,10 @@ D_ENTER; stat_cache = efsd_hash_new(1023, 10, (EfsdHashFunc)efsd_hash_string, - (EfsdCmpFunc)strcmp, stat_hash_item_free); + (EfsdCmpFunc)strcmp, (EfsdFunc)stat_hash_item_free); lstat_cache = efsd_hash_new(1023, 10, (EfsdHashFunc)efsd_hash_string, - (EfsdCmpFunc)strcmp, stat_hash_item_free); + (EfsdCmpFunc)strcmp, (EfsdFunc)stat_hash_item_free); stat_lock = efsd_lock_new(); @@ -217,8 +217,8 @@ { D_ENTER; - efsd_hash_free_with_func(stat_cache, stat_hash_item_free_no_monitor_update); - efsd_hash_free_with_func(lstat_cache, stat_hash_item_free_no_monitor_update); + efsd_hash_free_with_func(stat_cache, (EfsdFunc)stat_hash_item_free_no_monitor_update); + efsd_hash_free_with_func(lstat_cache, (EfsdFunc)stat_hash_item_free_no_monitor_update); efsd_lock_free(stat_lock); stat_cache = NULL; =================================================================== RCS file: /cvsroot/enlightenment/e17/apps/efsd/efsd/libefsd.c,v retrieving revision 1.56 retrieving revision 1.57 diff -u -3 -r1.56 -r1.57 --- libefsd.c 21 Dec 2001 00:01:51 -0000 1.56 +++ libefsd.c 14 May 2002 09:46:18 -0000 1.57 @@ -51,6 +51,7 @@ #include <efsd_options.h> #include <efsd_types.h> #include <efsd_queue.h> +#include <efsd_hash.h> #include <libefsd_misc.h> #include <libefsd.h> @@ -74,6 +75,9 @@ }; +static EfsdHash *callbacks_hash = NULL; + + static char *libefsd_get_full_path(char *file); static int libefsd_send_command(EfsdConnection *ec, EfsdCommand *com); static EfsdCmdId libefsd_get_next_id(void); @@ -92,6 +96,8 @@ static void libefsd_cmd_queue_add_command(EfsdConnection *ec, EfsdCommand *com); static void libefsd_cmd_queue_process(EfsdConnection *ec); +static void libefsd_callbacks_init(void); + static char* libefsd_get_full_path(char *file) { @@ -345,6 +351,39 @@ } +static void +libefsd_hash_item_free(EfsdHashItem *it) +{ + D_ENTER; + + if (!it) + D_RETURN; + + FREE(it->key); + efsd_callbacks_cleanup((EfsdEventCallbacks*) it->data); + FREE(it); + + D_RETURN; +} + + +static void +libefsd_callbacks_init(void) +{ + D_ENTER; + + if (callbacks_hash) + D_RETURN; + + callbacks_hash = efsd_hash_new(1023, 100, (EfsdHashFunc)efsd_hash_int, + (EfsdCmpFunc)efsd_hash_cmp_int, + (EfsdFunc)libefsd_hash_item_free); + + D_RETURN; +} + + + /* Efsd API starts here --------------------------------------------- */ @@ -492,6 +531,119 @@ } +int +efsd_dispatch_event(EfsdEvent *ev) +{ + EfsdEventCallbacks *callbacks = NULL; + EfsdCmdId id = 0; + int handled = FALSE; + + D_ENTER; + + if (!ev) + D_RETURN_(-1); + + if ( (id = efsd_event_id(ev)) < 0) + D_RETURN_(-1); + + callbacks = + (EfsdEventCallbacks*) efsd_hash_find(callbacks_hash, (void*) id); + + if (!callbacks) + D_RETURN_(FALSE); + + switch (ev->type) + { + case EFSD_EVENT_FILECHANGE: + switch (ev->efsd_filechange_event.changetype) + { + case EFSD_FILE_CHANGED: + if (callbacks->changed_cb) + { + callbacks->changed_cb(&(ev->efsd_filechange_event)); + handled = TRUE; + } + break; + case EFSD_FILE_DELETED: + if (callbacks->delete_cb) + { + callbacks->delete_cb(&(ev->efsd_filechange_event)); + handled = TRUE; + } + break; + case EFSD_FILE_START_EXEC: + if (callbacks->startexec_cb) + { + callbacks->startexec_cb(&(ev->efsd_filechange_event)); + handled = TRUE; + } + break; + case EFSD_FILE_STOP_EXEC: + if (callbacks->stopexec_cb) + { + callbacks->stopexec_cb(&(ev->efsd_filechange_event)); + handled = TRUE; + } + break; + case EFSD_FILE_CREATED: + if (callbacks->created_cb) + { + callbacks->created_cb(&(ev->efsd_filechange_event)); + handled = TRUE; + } + break; + case EFSD_FILE_MOVED: + if (callbacks->moved_cb) + { + callbacks->moved_cb(&(ev->efsd_filechange_event)); + handled = TRUE; + } + break; + case EFSD_FILE_ACKNOWLEDGE: + if (callbacks->ack_cb) + { + callbacks->ack_cb(&(ev->efsd_filechange_event)); + handled = TRUE; + } + break; + case EFSD_FILE_EXISTS: + if (callbacks->exists_cb) + { + callbacks->exists_cb(&(ev->efsd_filechange_event)); + handled = TRUE; + } + break; + case EFSD_FILE_END_EXISTS: + if (callbacks->endexists_cb) + { + callbacks->endexists_cb(&(ev->efsd_filechange_event)); + handled = TRUE; + } + break; + default: + D_RETURN_(-1); + } + break; + case EFSD_EVENT_REPLY: + if (callbacks->reply_cb) + { + callbacks->reply_cb(&(ev->efsd_reply_event)); + } + break; + case EFSD_EVENT_METADATA_CHANGE: + if (callbacks->metadata_cb) + { + callbacks->metadata_cb(&(ev->efsd_metachange_event)); + } + break; + default: + D_RETURN_(-1); + } + + D_RETURN_(handled); +} + + int efsd_commands_pending(EfsdConnection *ec) { @@ -1317,3 +1469,61 @@ D_RETURN_(NULL); } + +EfsdEventCallbacks * +efsd_callbacks_create(void) +{ + EfsdEventCallbacks *cbs = NULL; + + D_ENTER; + + if (! (cbs = NEW(EfsdEventCallbacks))) + D_RETURN_(NULL); + + memset(cbs, 0, sizeof(EfsdEventCallbacks)); + + D_RETURN_(cbs); +} + + +void +efsd_callbacks_cleanup(EfsdEventCallbacks *callbacks) +{ + D_ENTER; + + FREE(callbacks); + + D_RETURN; +} + + +EfsdEventCallbacks * +efsd_callbacks_register(EfsdCmdId id, EfsdEventCallbacks *callbacks) +{ + EfsdEventCallbacks *old_callbacks = NULL; + + D_ENTER; + + /* Make sure the hashtable is initialized ... */ + libefsd_callbacks_init(); + + /* Try to change the value. If old_callbacks is NULL, it didn't work. */ + old_callbacks = efsd_hash_change_val(callbacks_hash, (void*) id, + (void*) callbacks); + + /* If callbacks is NULL, the user wants to remove the callbacks: */ + if (!callbacks) + efsd_hash_remove(callbacks_hash, (void*) id, NULL); + + /* If we got old callbacks, return them. */ + if (old_callbacks) + { + D_RETURN_(old_callbacks); + } + else /* otherwise, this is a new insertion for this id. */ + { + efsd_hash_insert(callbacks_hash, (void*) id, (void*) callbacks); + } + + D_RETURN_(NULL); +} =================================================================== RCS file: /cvsroot/enlightenment/e17/apps/efsd/efsd/libefsd.h,v retrieving revision 1.44 retrieving revision 1.45 diff -u -3 -r1.44 -r1.45 --- libefsd.h 26 Nov 2001 01:06:38 -0000 1.44 +++ libefsd.h 14 May 2002 09:46:18 -0000 1.45 @@ -44,6 +44,34 @@ typedef struct efsd_connection EfsdConnection; typedef struct efsd_options EfsdOptions; + +/* Function prototype typedefs for the various file change + event handlers: */ + +typedef void (*EfsdFileEventFunc) (EfsdFileChangeEvent *ev); +typedef void (*EfsdFileMetadataEventFunc) (EfsdMetadataChangeEvent *ev); +typedef void (*EfsdReplyFunc) (EfsdReplyEvent *ev); + +/* And a struct that puts them all together. Look at the + efsd_callbacks_... functions */ +typedef struct efsd_event_callbacks +{ + EfsdFileEventFunc changed_cb; + EfsdFileEventFunc delete_cb; + EfsdFileEventFunc startexec_cb; + EfsdFileEventFunc stopexec_cb; + EfsdFileEventFunc created_cb; + EfsdFileEventFunc moved_cb; + EfsdFileEventFunc ack_cb; + EfsdFileEventFunc exists_cb; + EfsdFileEventFunc endexists_cb; + EfsdFileMetadataEventFunc metadata_cb; + EfsdReplyFunc reply_cb; +} +EfsdEventCallbacks; + + + /** * efsd_open - Creates and returns an efsd connection. * @@ -101,6 +129,21 @@ int efsd_next_event(EfsdConnection *ec, EfsdEvent *ev); +/** + * efsd_dispatch_event - handles events through the dispatching mechanism. + * @ev: The Efsd event to dispatch. + * + * This function looks up the set of callbacks for the command ID contained + * in the event, and then dispatches this event to the appropriate callback. + * If no set of callbacks is found or the matching callback isn't defined + * in the EfsdEventCallbacks struct, nothing happens. + * + * Returns -1 when an error occurs, FALSE when the event didn't get + * dispatched, and TRUE when it got dispatched. + */ +int efsd_dispatch_event(EfsdEvent *ev); + + /** * efsd_wait_event - blocking wait for next Efsd event. * @ec: The Efsd connection @@ -697,6 +740,39 @@ * %EFSD_FILE_EXISTS also for hidden files (starting with a '.'). */ EfsdOption *efsd_op_list_all(void); + + + +/** + * efsd_callbacks_create - returns an initialized event callback struct. + * + */ +EfsdEventCallbacks *efsd_callbacks_create(void); + +/** + * efsd_callbacks_cleanup - cleans up memory occupied by a callbacks struct. + * @callbacks: callbacks structure to clean up. + */ +void efsd_callbacks_cleanup(EfsdEventCallbacks *callbacks); + + +/** + * efsd_callbacks_register - registers a set of handlers for a particular monitor. + * @id: Command ID of the monitoring request. + * @callbacks: Initialized callback set. + * + * You can register a set of event handlers for a particular file monitor + * here. Pass the command ID that was returned by the corresponding + * monitor request call as first argument, and an EfsdEventCallback struct + * that is initialized properly second. You don't need to initialize + * callbacks you don't want to use. + * + * If you want to change the set of callbacks for an ID, just call this + * function again, you'll get the old set in return (and NULL otherwise). + * Similarly, if you want to remove a callback set for a command ID, just + * pass NULL as the second argument. + */ +EfsdEventCallbacks *efsd_callbacks_register(EfsdCmdId id, EfsdEventCallbacks *callbacks); #ifdef __cplusplus } =================================================================== RCS file: /cvsroot/enlightenment/e17/apps/efsd/efsd/libefsd_misc.c,v retrieving revision 1.4 retrieving revision 1.5 diff -u -3 -r1.4 -r1.5 --- libefsd_misc.c 26 Nov 2001 01:06:38 -0000 1.4 +++ libefsd_misc.c 14 May 2002 09:46:18 -0000 1.5 @@ -128,9 +128,9 @@ if (s[0] != '\0') D_RETURN_(s); #ifndef __EMX__ - snprintf(s, sizeof(s), "%s/efsd_socket", misc_get_user_dir()); + snprintf(s, sizeof(s), "/tmp/.efsd_socket_%u", geteuid()); #else - snprintf(s, sizeof(s), "\\socket\\%s/efsd_socket", misc_get_user_dir()); + snprintf(s, sizeof(s), "\\socket\\.efsd_socket_%u", geteuid()); #endif s[sizeof(s)-1] = '\0'; D_RETURN_(s); |
From: <enl...@li...> - 2002-05-14 09:46:49
|
Enlightenment CVS committal Author : cpk Project : e17 Module : apps/efsd Dir : e17/apps/efsd/doc Modified Files: efsd-manual.sgml Log Message: Updating HEAD to SPLIT's state... =================================================================== RCS file: /cvsroot/enlightenment/e17/apps/efsd/doc/efsd-manual.sgml,v retrieving revision 1.23 retrieving revision 1.24 diff -u -3 -r1.23 -r1.24 --- efsd-manual.sgml 26 Nov 2001 01:06:37 -0000 1.23 +++ efsd-manual.sgml 14 May 2002 09:46:17 -0000 1.24 @@ -1411,6 +1411,51 @@ <refentry> <refmeta> +<refentrytitle><phrase id="API-efsd-dispatch-event">efsd_dispatch_event</phrase></refentrytitle> +</refmeta> +<refnamediv> + <refname>efsd_dispatch_event</refname> + <refpurpose> + handles events through the dispatching mechanism. + </refpurpose> +</refnamediv> +<refsynopsisdiv> + <title>Synopsis</title> + <funcsynopsis> + <funcdef>int <function>efsd_dispatch_event </function></funcdef> + <paramdef>EfsdEvent * <parameter>ev</parameter></paramdef> + </funcsynopsis> +</refsynopsisdiv> +<refsect1> + <title>Arguments</title> + <variablelist> + <varlistentry> + <term><parameter>ev</parameter></term> + <listitem> + <para> + The Efsd event to dispatch. + </para> + </listitem> + </varlistentry> + </variablelist> +</refsect1> +<refsect1> + <title>Description</title> + <para> + This function looks up the set of callbacks for the command ID contained + in the event, and then dispatches this event to the appropriate callback. + If no set of callbacks is found or the matching callback isn't defined + in the EfsdEventCallbacks struct, nothing happens. + </para><para> + + Returns -1 when an error occurs, FALSE when the event didn't get + dispatched, and TRUE when it got dispatched. + </para> +</refsect1> +</refentry> + +<refentry> +<refmeta> <refentrytitle><phrase id="API-efsd-wait-event">efsd_wait_event</phrase></refentrytitle> </refmeta> <refnamediv> @@ -3711,6 +3756,131 @@ This option constructor returns an EfsdOption that causes Efsd to send <constant>EFSD_FILE_EXISTS</constant> also for hidden files (starting with a '.'). + </para> +</refsect1> +</refentry> + +<refentry> +<refmeta> +<refentrytitle><phrase id="API-efsd-callbacks-create">efsd_callbacks_create</phrase></refentrytitle> +</refmeta> +<refnamediv> + <refname>efsd_callbacks_create</refname> + <refpurpose> + returns an initialized event callback struct. + </refpurpose> +</refnamediv> +<refsynopsisdiv> + <title>Synopsis</title> + <funcsynopsis> + <funcdef>EfsdEventCallbacks * <function>efsd_callbacks_create </function></funcdef> + <paramdef> <parameter>void</parameter></paramdef> + </funcsynopsis> +</refsynopsisdiv> +<refsect1> + <title>Arguments</title> + <variablelist> + <varlistentry> + <term><parameter>void</parameter></term> + <listitem> + <para> + </para> + </listitem> + </varlistentry> + </variablelist> +</refsect1> +<refsect1> + <title>Description</title> + <para> + </para> +</refsect1> +</refentry> + +<refentry> +<refmeta> +<refentrytitle><phrase id="API-efsd-callbacks-cleanup">efsd_callbacks_cleanup</phrase></refentrytitle> +</refmeta> +<refnamediv> + <refname>efsd_callbacks_cleanup</refname> + <refpurpose> + cleans up memory occupied by a callbacks struct. + </refpurpose> +</refnamediv> +<refsynopsisdiv> + <title>Synopsis</title> + <funcsynopsis> + <funcdef>void <function>efsd_callbacks_cleanup </function></funcdef> + <paramdef>EfsdEventCallbacks * <parameter>callbacks</parameter></paramdef> + </funcsynopsis> +</refsynopsisdiv> +<refsect1> + <title>Arguments</title> + <variablelist> + <varlistentry> + <term><parameter>callbacks</parameter></term> + <listitem> + <para> + callbacks structure to clean up. + </para> + </listitem> + </varlistentry> + </variablelist> +</refsect1> +</refentry> + +<refentry> +<refmeta> +<refentrytitle><phrase id="API-efsd-callbacks-register">efsd_callbacks_register</phrase></refentrytitle> +</refmeta> +<refnamediv> + <refname>efsd_callbacks_register</refname> + <refpurpose> + registers a set of handlers for a particular monitor. + </refpurpose> +</refnamediv> +<refsynopsisdiv> + <title>Synopsis</title> + <funcsynopsis> + <funcdef>EfsdEventCallbacks * <function>efsd_callbacks_register </function></funcdef> + <paramdef>EfsdCmdId <parameter>id</parameter></paramdef> + <paramdef>EfsdEventCallbacks * <parameter>callbacks</parameter></paramdef> + </funcsynopsis> +</refsynopsisdiv> +<refsect1> + <title>Arguments</title> + <variablelist> + <varlistentry> + <term><parameter>id</parameter></term> + <listitem> + <para> + Command ID of the monitoring request. + </para> + </listitem> + </varlistentry> + <varlistentry> + <term><parameter>callbacks</parameter></term> + <listitem> + <para> + Initialized callback set. + </para> + </listitem> + </varlistentry> + </variablelist> +</refsect1> +<refsect1> + <title>Description</title> + <para> + You can register a set of event handlers for a particular file monitor + here. Pass the command ID that was returned by the corresponding + monitor request call as first argument, and an EfsdEventCallback struct + that is initialized properly second. You don't need to initialize + callbacks you don't want to use. + </para><para> + + If you want to change the set of callbacks for an ID, just call this + function again, you'll get the old set in return (and NULL otherwise). + Similarly, if you want to remove a callback set for a command ID, just + pass NULL as the second argument. </para> </refsect1> </refentry> |