@@ -471,119 +471,15 @@ BOOL store_object::get_all_proptags(PROPTAG_ARRAY *pproptags)
471471 return TRUE ;
472472}
473473
474- static constexpr struct cfg_directive oof_defaults[] = {
475- {" allow_external_oof" , " 0" , CFG_BOOL},
476- {" external_audience" , " 0" , CFG_BOOL},
477- {" oof_state" , " 0" },
478- CFG_TABLE_END,
479- };
480-
481474static void *store_object_get_oof_property (const char *maildir,
482- proptag_t proptag) try
475+ proptag_t proptag)
483476{
484- int offset;
485- char *pbuff;
486- int buff_len;
487- void *pvalue;
488- const char *str_value;
489- char subject[1024 ];
490- MIME_FIELD mime_field;
491- struct stat node_stat;
492- static constexpr uint8_t fake_true = true ;
493- static constexpr uint8_t fake_false = false ;
494- std::string path;
495-
496- switch (proptag) {
497- case PR_EC_OUTOFOFFICE:
498- case PR_EC_OUTOFOFFICE_FROM:
499- case PR_EC_OUTOFOFFICE_UNTIL:
500- case PR_EC_ALLOW_EXTERNAL:
501- case PR_EC_EXTERNAL_AUDIENCE:
502- path = maildir + " /config/autoreply.cfg" s;
503- break ;
504- case PR_EC_OUTOFOFFICE_MSG:
505- case PR_EC_OUTOFOFFICE_SUBJECT:
506- path = maildir + " /config/internal-reply" s;
507- break ;
508- case PR_EC_EXTERNAL_REPLY:
509- case PR_EC_EXTERNAL_SUBJECT:
510- path = maildir + " /config/external-reply" s;
511- break ;
512- }
513-
514- switch (proptag) {
515- case PR_EC_OUTOFOFFICE: {
516- auto oofstate = cu_alloc<uint32_t >();
517- if (oofstate == nullptr )
518- return NULL ;
519- pvalue = oofstate;
520- auto pconfig = config_file_init (path.c_str (), oof_defaults);
521- *oofstate = pconfig != nullptr ? pconfig->get_ll (" oof_state" ) : 0 ;
522- return pvalue;
523- }
524- case PR_EC_OUTOFOFFICE_MSG:
525- case PR_EC_EXTERNAL_REPLY: {
526- wrapfd fd = open (path.c_str (), O_RDONLY);
527- if (fd.get () < 0 || fstat (fd.get (), &node_stat) != 0 )
528- return nullptr ;
529- buff_len = node_stat.st_size ;
530- pbuff = cu_alloc<char >(buff_len + 1 );
531- if (pbuff == nullptr || read (fd.get (), pbuff, buff_len) != buff_len)
532- return NULL ;
533- pbuff[buff_len] = ' \0 ' ;
534- auto ptr = strstr (pbuff, " \r\n\r\n " );
535- return ptr != nullptr ? ptr + 4 : nullptr ;
536- }
537- case PR_EC_OUTOFOFFICE_SUBJECT:
538- case PR_EC_EXTERNAL_SUBJECT: {
539- wrapfd fd = open (path.c_str (), O_RDONLY);
540- if (fd.get () < 0 || fstat (fd.get (), &node_stat) != 0 )
541- return NULL ;
542- buff_len = node_stat.st_size ;
543- pbuff = cu_alloc<char >(buff_len);
544- if (pbuff == nullptr || read (fd.get (), pbuff, buff_len) != buff_len)
545- return NULL ;
546- offset = 0 ;
547- size_t parsed_length;
548- while ((parsed_length = parse_mime_field (pbuff + offset, buff_len - offset, &mime_field)) != 0 ) {
549- offset += parsed_length;
550- if (strcasecmp (mime_field.name .c_str (), " Subject" ) == 0 &&
551- mime_field.value .size () < std::size (subject) &&
552- mime_string_to_utf8 (" utf-8" , mime_field.value .c_str (), subject,
553- std::size (subject)))
554- return common_util_dup (subject);
555- if (pbuff[offset] == ' \r ' && pbuff[offset+1 ] == ' \n ' )
556- return NULL ;
557- }
558- return NULL ;
559- }
560- case PR_EC_OUTOFOFFICE_FROM:
561- case PR_EC_OUTOFOFFICE_UNTIL: {
562- auto pconfig = config_file_init (path.c_str (), oof_defaults);
563- if (pconfig == nullptr )
564- return NULL ;
565- pvalue = cu_alloc<uint64_t >();
566- if (pvalue == nullptr )
567- return NULL ;
568- str_value = pconfig->get_value (proptag == PR_EC_OUTOFOFFICE_FROM ? " START_TIME" : " END_TIME" );
569- if (str_value == nullptr )
570- return NULL ;
571- *static_cast <uint64_t *>(pvalue) = rop_util_unix_to_nttime (strtoll (str_value, nullptr , 0 ));
572- return pvalue;
573- }
574- case PR_EC_ALLOW_EXTERNAL:
575- case PR_EC_EXTERNAL_AUDIENCE: {
576- auto pconfig = config_file_init (path.c_str (), oof_defaults);
577- if (pconfig == nullptr )
578- return deconst (&fake_false);
579- auto key = proptag == PR_EC_ALLOW_EXTERNAL ? " allow_external_oof" : " external_audience" ;
580- pvalue = deconst (pconfig->get_ll (key) == 0 ? &fake_false : &fake_true);
581- return pvalue;
582- }
583- }
584- return NULL ;
585- } catch (const std::bad_alloc &) {
586- return nullptr ;
477+ const PROPTAG_ARRAY tags = {1 , &proptag};
478+ TPROPVAL_ARRAY props{};
479+ if (!exmdb_client->autoreply_getprop (maildir, CP_UTF8, &tags, &props) ||
480+ props.count == 0 || props[0 ].proptag != proptag)
481+ return nullptr ;
482+ return props[0 ].pvalue ;
587483}
588484
589485static BOOL store_object_get_calculated_property (store_object *pstore,
@@ -1060,140 +956,10 @@ BOOL store_object::get_properties(const PROPTAG_ARRAY *pproptags,
1060956static BOOL store_object_set_oof_property (const char *maildir,
1061957 proptag_t proptag, const void *pvalue)
1062958{
1063- char *pbuff;
1064- int buff_len;
1065- char *ptoken;
1066- std::string autoreply_path;
1067-
1068- try {
1069- autoreply_path = maildir + " /config/autoreply.cfg" s;
1070- } catch (const std::bad_alloc &) {
1071- mlog (LV_ERR, " E-1483: ENOMEM" );
1072- return false ;
1073- }
1074- /* Ensure file exists for config_file_prg */
1075- auto fdtest = open (autoreply_path.c_str (), O_CREAT | O_WRONLY, FMODE_PUBLIC);
1076- if (fdtest < 0 )
1077- return false ;
1078- close (fdtest);
1079- switch (proptag) {
1080- case PR_EC_OUTOFOFFICE: {
1081- auto pconfig = config_file_init (autoreply_path.c_str (), oof_defaults);
1082- if (pconfig == nullptr )
1083- return FALSE ;
1084- auto v = *static_cast <const uint32_t *>(pvalue);
1085- pconfig->set_value (" OOF_STATE" , v == 1 ? " 1" : v == 2 ? " 2" : " 0" );
1086- return pconfig->save ();
1087- }
1088- case PR_EC_OUTOFOFFICE_FROM:
1089- case PR_EC_OUTOFOFFICE_UNTIL: {
1090- auto pconfig = config_file_init (autoreply_path.c_str (), oof_defaults);
1091- if (pconfig == nullptr )
1092- return FALSE ;
1093- long long t = rop_util_nttime_to_unix (*static_cast <const uint64_t *>(pvalue));
1094- pconfig->set_value (proptag == PR_EC_OUTOFOFFICE_FROM ?
1095- " START_TIME" : " END_TIME" , std::to_string (t).c_str ());
1096- return pconfig->save ();
1097- }
1098- case PR_EC_OUTOFOFFICE_MSG:
1099- case PR_EC_EXTERNAL_REPLY: {
1100- try {
1101- autoreply_path = maildir;
1102- autoreply_path += proptag == PR_EC_OUTOFOFFICE_MSG ?
1103- " /config/internal-reply" : " /config/external-reply" ;
1104- } catch (const std::bad_alloc &) {
1105- mlog (LV_ERR, " E-1484: ENOMEM" );
1106- return false ;
1107- }
1108- wrapfd fd = open (autoreply_path.c_str (), O_RDONLY);
1109- struct stat node_stat;
1110- if (fd.get () < 0 || fstat (fd.get (), &node_stat) != 0 ) {
1111- buff_len = strlen (static_cast <const char *>(pvalue));
1112- pbuff = cu_alloc<char >(buff_len + 256 );
1113- if (pbuff == nullptr )
1114- return FALSE ;
1115- buff_len = gx_snprintf (pbuff, buff_len + 256 ,
1116- " Content-Type: text/html; charset=\" utf-8\"\r\n\r\n %s" ,
1117- static_cast <const char *>(pvalue));
1118- } else {
1119- buff_len = node_stat.st_size ;
1120- pbuff = cu_alloc<char >(buff_len + strlen (static_cast <const char *>(pvalue)) + 1 );
1121- if (pbuff == nullptr || read (fd.get (), pbuff, buff_len) != buff_len)
1122- return FALSE ;
1123- pbuff[buff_len] = ' \0 ' ;
1124- ptoken = strstr (pbuff, " \r\n\r\n " );
1125- if (NULL != ptoken) {
1126- strcpy (ptoken + 4 , static_cast <const char *>(pvalue));
1127- buff_len = strlen (pbuff);
1128- } else {
1129- buff_len = sprintf (pbuff, " Content-Type: text/html;\r\n "
1130- " \t charset=\" utf-8\"\r\n\r\n %s" ,
1131- static_cast <const char *>(pvalue));
1132- }
1133- }
1134- fd = open (autoreply_path.c_str (), O_CREAT | O_TRUNC | O_WRONLY, FMODE_PUBLIC);
1135- if (fd.get () < 0 || write (fd.get (), pbuff, buff_len) != buff_len)
1136- return FALSE ;
1137- return TRUE ;
1138- }
1139- case PR_EC_OUTOFOFFICE_SUBJECT:
1140- case PR_EC_EXTERNAL_SUBJECT: {
1141- try {
1142- autoreply_path = maildir;
1143- autoreply_path += proptag == PR_EC_OUTOFOFFICE_SUBJECT ?
1144- " /config/internal-reply" : " /config/external-reply" ;
1145- } catch (const std::bad_alloc &) {
1146- mlog (LV_ERR, " E-1485: ENOMEM" );
1147- return false ;
1148- }
1149- struct stat node_stat;
1150- wrapfd fd = open (autoreply_path.c_str (), O_RDONLY);
1151- if (fd.get () < 0 || fstat (fd.get (), &node_stat) != 0 ) {
1152- buff_len = strlen (static_cast <const char *>(pvalue));
1153- pbuff = cu_alloc<char >(buff_len + 256 );
1154- if (pbuff == nullptr )
1155- return FALSE ;
1156- buff_len = sprintf (pbuff, " Content-Type: text/html;\r\n\t "
1157- " charset=\" utf-8\"\r\n Subject: %s\r\n\r\n " ,
1158- static_cast <const char *>(pvalue));
1159- } else {
1160- buff_len = node_stat.st_size ;
1161- pbuff = cu_alloc<char >(buff_len + strlen (static_cast <const char *>(pvalue)) + 16 );
1162- if (pbuff == nullptr )
1163- return FALSE ;
1164- ptoken = cu_alloc<char >(buff_len + 1 );
1165- if (ptoken == nullptr )
1166- return FALSE ;
1167- if (read (fd.get (), ptoken, buff_len) != buff_len)
1168- return FALSE ;
1169- ptoken[buff_len] = ' \0 ' ;
1170- ptoken = strstr (ptoken, " \r\n\r\n " );
1171- if (ptoken == nullptr )
1172- buff_len = sprintf (pbuff, " Content-Type: text/html;\r\n\t "
1173- " charset=\" utf-8\"\r\n Subject: %s\r\n\r\n " ,
1174- static_cast <const char *>(pvalue));
1175- else
1176- buff_len = sprintf (pbuff, " Content-Type: text/html;\r\n\t "
1177- " charset=\" utf-8\"\r\n Subject: %s%s" ,
1178- static_cast <const char *>(pvalue), ptoken);
1179- }
1180- fd = open (autoreply_path.c_str (), O_CREAT | O_TRUNC | O_WRONLY, FMODE_PUBLIC);
1181- if (fd.get () < 0 || write (fd.get (), pbuff, buff_len) != buff_len)
1182- return FALSE ;
1183- return TRUE ;
1184- }
1185- case PR_EC_ALLOW_EXTERNAL:
1186- case PR_EC_EXTERNAL_AUDIENCE: {
1187- auto pconfig = config_file_init (autoreply_path.c_str (), oof_defaults);
1188- if (pconfig == nullptr )
1189- return FALSE ;
1190- pconfig->set_value (proptag == PR_EC_ALLOW_EXTERNAL ?
1191- " ALLOW_EXTERNAL_OOF" : " EXTERNAL_AUDIENCE" ,
1192- *static_cast <const uint8_t *>(pvalue) == 0 ? " 0" : " 1" );
1193- return pconfig->save ();
1194- }
1195- }
1196- return FALSE ;
959+ const TAGGED_PROPVAL pv = {proptag, deconst (pvalue)};
960+ const TPROPVAL_ARRAY vals = {1 , deconst (&pv)};
961+ PROBLEM_ARRAY status{};
962+ return exmdb_client->autoreply_setprop (maildir, CP_UTF8, &vals, &status);
1197963}
1198964
1199965static BOOL store_object_set_folder_name (store_object *pstore,
0 commit comments