00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251
00252
00253
00254
00255
00256
00257
00258
00259
00260
00261
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284
00285
00286
00287
00288
00289
00290
00291
00292 #ifndef DOXYGEN_SHOULD_SKIP_THIS
00293
00294
00295 #include "midas.h"
00296 #include "msystem.h"
00297
00298 static INT ss_in_async_routine_flag = 0;
00299 #ifdef LOCAL_ROUTINES
00300 #include <signal.h>
00301
00302
00303
00304
00305
00306 BOOL disable_shm_write = FALSE;
00307
00308
00309 INT ss_set_async_flag(INT flag)
00310
00311
00312
00313
00314
00315
00316
00317
00318
00319
00320
00321
00322
00323
00324
00325
00326
00327
00328
00329 {
00330 INT old_flag;
00331
00332 old_flag = ss_in_async_routine_flag;
00333 ss_in_async_routine_flag = flag;
00334 return old_flag;
00335 }
00336
00337
00338 INT ss_shm_open(char *name, INT size, void **adr, HNDLE * handle)
00339
00340
00341
00342
00343
00344
00345
00346
00347
00348
00349
00350
00351
00352
00353
00354
00355
00356
00357
00358
00359
00360
00361
00362 {
00363 INT status;
00364 char mem_name[256], file_name[256], path[256];
00365
00366
00367 sprintf(mem_name, "SM_%s", name);
00368
00369
00370 cm_get_path(path);
00371 if (path[0] == 0) {
00372 getcwd(path, 256);
00373 #if defined(OS_VMS)
00374 #elif defined(OS_UNIX)
00375 strcat(path, "/");
00376 #elif defined(OS_WINNT)
00377 strcat(path, "\\");
00378 #endif
00379 }
00380
00381 strcpy(file_name, path);
00382 #if defined (OS_UNIX)
00383 strcat(file_name, ".");
00384 #endif
00385 strcat(file_name, name);
00386 strcat(file_name, ".SHM");
00387
00388 #ifdef OS_WINNT
00389
00390 status = SS_SUCCESS;
00391
00392 {
00393 HANDLE hFile, hMap;
00394 char str[256], *p;
00395 DWORD file_size;
00396
00397
00398
00399
00400
00401 strcpy(str, path);
00402
00403
00404 while (strpbrk(str, "\\: "))
00405 *strpbrk(str, "\\: ") = '*';
00406 strcat(str, mem_name);
00407
00408
00409 p = str;
00410 while (*p)
00411 *p++ = (char) toupper(*p);
00412
00413 hMap = OpenFileMapping(FILE_MAP_ALL_ACCESS, FALSE, str);
00414 if (hMap == 0) {
00415 hFile = CreateFile(file_name, GENERIC_READ | GENERIC_WRITE,
00416 FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
00417 OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);
00418 if (!hFile) {
00419 cm_msg(MERROR, "ss_shm_open", "CreateFile() failed");
00420 return SS_FILE_ERROR;
00421 }
00422
00423 file_size = GetFileSize(hFile, NULL);
00424 if (file_size != 0xFFFFFFFF && file_size > 0)
00425 size = file_size;
00426
00427 hMap = CreateFileMapping(hFile, NULL, PAGE_READWRITE, 0, size, str);
00428
00429 if (!hMap) {
00430 status = GetLastError();
00431 cm_msg(MERROR, "ss_shm_open",
00432 "CreateFileMapping() failed, error %d", status);
00433 return SS_FILE_ERROR;
00434 }
00435
00436 CloseHandle(hFile);
00437 status = SS_CREATED;
00438 }
00439
00440 *adr = MapViewOfFile(hMap, FILE_MAP_ALL_ACCESS, 0, 0, 0);
00441 *handle = (HNDLE) hMap;
00442
00443 if (adr == NULL) {
00444 cm_msg(MERROR, "ss_shm_open", "MapViewOfFile() failed");
00445 return SS_NO_MEMORY;
00446 }
00447
00448 return status;
00449 }
00450
00451 #endif
00452 #ifdef OS_VMS
00453
00454 status = SS_SUCCESS;
00455
00456 {
00457 int addr[2];
00458 $DESCRIPTOR(memname_dsc, "dummy");
00459 $DESCRIPTOR(filename_dsc, "dummy");
00460 memname_dsc.dsc$w_length = strlen(mem_name);
00461 memname_dsc.dsc$a_pointer = mem_name;
00462 filename_dsc.dsc$w_length = strlen(file_name);
00463 filename_dsc.dsc$a_pointer = file_name;
00464
00465 addr[0] = size;
00466 addr[1] = 0;
00467
00468 status = ppl$create_shared_memory(&memname_dsc, addr,
00469 &PPL$M_NOUNI, &filename_dsc);
00470
00471 if (status == PPL$_CREATED)
00472 status = SS_CREATED;
00473 else if (status != PPL$_NORMAL)
00474 status = SS_FILE_ERROR;
00475
00476 *adr = (void *) addr[1];
00477 *handle = 0;
00478
00479 if (adr == NULL)
00480 return SS_NO_MEMORY;
00481
00482 return status;
00483 }
00484
00485 #endif
00486 #ifdef OS_UNIX
00487
00488 status = SS_SUCCESS;
00489
00490 {
00491 int key, shmid, fh, file_size;
00492 struct shmid_ds buf;
00493 char str[256];
00494
00495
00496 key = ftok(file_name, 'M');
00497
00498
00499 if (key == -1) {
00500 fh = open(file_name, O_CREAT | O_TRUNC | O_BINARY, 0644);
00501 close(fh);
00502 key = ftok(file_name, 'M');
00503
00504 if (key == -1) {
00505 cm_msg(MERROR, "ss_shm_open", "ftok() failed");
00506 return SS_FILE_ERROR;
00507 }
00508
00509 status = SS_CREATED;
00510
00511
00512
00513 shmid = shmget(key, 0, 0);
00514 shmctl(shmid, IPC_RMID, &buf);
00515 } else {
00516
00517 file_size = (INT) ss_file_size(file_name);
00518 if (file_size > 0)
00519 size = file_size;
00520 }
00521
00522
00523 shmid = shmget(key, size, 0);
00524 if (shmid == -1) {
00525 shmid = shmget(key, size, IPC_CREAT);
00526 status = SS_CREATED;
00527 }
00528
00529 if (shmid == -1) {
00530 if (errno == EINVAL)
00531 cm_msg(MERROR, "ss_shm_open",
00532 "shmget() failed, shared memory size %d exceeds system limit",
00533 size);
00534 else
00535 cm_msg(MERROR, "ss_shm_open", "shmget() failed, errno = %d",
00536 errno);
00537
00538 return SS_NO_MEMORY;
00539 }
00540
00541 buf.shm_perm.uid = getuid();
00542 buf.shm_perm.gid = getgid();
00543 buf.shm_perm.mode = 0666;
00544 shmctl(shmid, IPC_SET, &buf);
00545
00546 *adr = shmat(shmid, 0, 0);
00547 *handle = (HNDLE) shmid;
00548
00549 if ((*adr) == (void *) (-1)) {
00550 sprintf(str, "shmat() failed, errno = %d", errno);
00551 cm_msg(MERROR, "ss_shm_open", str);
00552 return SS_NO_MEMORY;
00553 }
00554
00555
00556 if (status == SS_CREATED) {
00557 fh = open(file_name, O_RDONLY, 0644);
00558 if (fh == -1)
00559 fh = open(file_name, O_CREAT | O_RDWR, 0644);
00560 else
00561 read(fh, *adr, size);
00562 close(fh);
00563 }
00564
00565 return status;
00566 }
00567
00568 #endif
00569 }
00570
00571
00572 INT ss_shm_close(char *name, void *adr, HNDLE handle, INT destroy_flag)
00573
00574
00575
00576
00577
00578
00579
00580
00581
00582
00583
00584
00585
00586
00587
00588
00589
00590
00591
00592
00593
00594
00595
00596 {
00597 char mem_name[256], file_name[256], path[256];
00598
00599
00600
00601
00602
00603 sprintf(mem_name, "SM_%s", name);
00604
00605
00606 cm_get_path(path);
00607 if (path[0] == 0) {
00608 getcwd(path, 256);
00609 #if defined(OS_VMS)
00610 #elif defined(OS_UNIX)
00611 strcat(path, "/");
00612 #elif defined(OS_WINNT)
00613 strcat(path, "\\");
00614 #endif
00615 }
00616
00617 strcpy(file_name, path);
00618 #if defined (OS_UNIX)
00619 strcat(file_name, ".");
00620 #endif
00621 strcat(file_name, name);
00622 strcat(file_name, ".SHM");
00623
00624 #ifdef OS_WINNT
00625
00626 if (!UnmapViewOfFile(adr))
00627 return SS_INVALID_ADDRESS;
00628
00629 CloseHandle((HANDLE) handle);
00630
00631 return SS_SUCCESS;
00632
00633 #endif
00634 #ifdef OS_VMS
00635
00636
00637
00638
00639
00640
00641
00642
00643
00644
00645
00646
00647
00648
00649
00650
00651
00652
00653
00654
00655
00656
00657
00658 return SS_INVALID_ADDRESS;
00659
00660 #endif
00661 #ifdef OS_UNIX
00662
00663 {
00664 struct shmid_ds buf;
00665 FILE *fh;
00666
00667
00668 if (shmctl(handle, IPC_STAT, &buf) < 0) {
00669 cm_msg(MERROR, "ss_shm_close", "shmctl() failed");
00670 return SS_INVALID_HANDLE;
00671 }
00672
00673
00674 if (buf.shm_nattch == 1) {
00675 if (!disable_shm_write) {
00676 fh = fopen(file_name, "w");
00677
00678 if (fh == NULL) {
00679 cm_msg(MERROR, "ss_shm_close",
00680 "Cannot write to file %s, please check protection",
00681 file_name);
00682 } else {
00683
00684 fwrite(adr, 1, buf.shm_segsz, fh);
00685 fclose(fh);
00686 }
00687 }
00688
00689 if (shmdt(adr) < 0) {
00690 cm_msg(MERROR, "ss_shm_close", "shmdt() failed");
00691 return SS_INVALID_ADDRESS;
00692 }
00693
00694 if (shmctl(handle, IPC_RMID, &buf) < 0) {
00695 cm_msg(MERROR, "ss_shm_close", "shmctl(RMID) failed");
00696 return SS_INVALID_ADDRESS;
00697 }
00698 } else
00699
00700 if (shmdt(adr) < 0) {
00701 cm_msg(MERROR, "ss_shm_close", "shmdt() failed");
00702 return SS_INVALID_ADDRESS;
00703 }
00704
00705 return SS_SUCCESS;
00706 }
00707
00708 #endif
00709 }
00710
00711
00712 INT ss_shm_protect(HNDLE handle, void *adr)
00713
00714
00715
00716
00717
00718
00719
00720
00721
00722
00723
00724
00725
00726
00727
00728
00729
00730
00731
00732 {
00733 #ifdef OS_WINNT
00734
00735 if (!UnmapViewOfFile(adr))
00736 return SS_INVALID_ADDRESS;
00737
00738 #endif
00739 #ifdef OS_UNIX
00740
00741 if (shmdt(adr) < 0) {
00742 cm_msg(MERROR, "ss_shm_protect", "shmdt() failed");
00743 return SS_INVALID_ADDRESS;
00744 }
00745 #endif
00746 return SS_SUCCESS;
00747 }
00748
00749
00750 INT ss_shm_unprotect(HNDLE handle, void **adr)
00751
00752
00753
00754
00755
00756
00757
00758
00759
00760
00761
00762
00763
00764
00765
00766
00767
00768
00769
00770 {
00771 #ifdef OS_WINNT
00772
00773 *adr = MapViewOfFile((HANDLE) handle, FILE_MAP_ALL_ACCESS, 0, 0, 0);
00774
00775 if (*adr == NULL) {
00776 cm_msg(MERROR, "ss_shm_unprotect", "MapViewOfFile() failed");
00777 return SS_NO_MEMORY;
00778 }
00779 #endif
00780 #ifdef OS_UNIX
00781
00782 *adr = shmat(handle, 0, 0);
00783
00784 if ((*adr) == (void *) (-1)) {
00785 cm_msg(MERROR, "ss_shm_unprotect", "shmat() failed, errno = %d",
00786 errno);
00787 return SS_NO_MEMORY;
00788 }
00789 #endif
00790
00791 return SS_SUCCESS;
00792 }
00793
00794
00795 INT ss_shm_flush(char *name, void *adr, INT size)
00796
00797
00798
00799
00800
00801
00802
00803
00804
00805
00806
00807
00808
00809
00810
00811
00812
00813
00814
00815 {
00816 char mem_name[256], file_name[256], path[256];
00817
00818
00819
00820
00821
00822 sprintf(mem_name, "SM_%s", name);
00823
00824
00825 cm_get_path(path);
00826 if (path[0] == 0) {
00827 getcwd(path, 256);
00828 #if defined(OS_VMS)
00829 #elif defined(OS_UNIX)
00830 strcat(path, "/");
00831 #elif defined(OS_WINNT)
00832 strcat(path, "\\");
00833 #endif
00834 }
00835
00836 strcpy(file_name, path);
00837 #if defined (OS_UNIX)
00838 strcat(file_name, ".");
00839 #endif
00840 strcat(file_name, name);
00841 strcat(file_name, ".SHM");
00842
00843 #ifdef OS_WINNT
00844
00845 if (!FlushViewOfFile(adr, size))
00846 return SS_INVALID_ADDRESS;
00847
00848 return SS_SUCCESS;
00849
00850 #endif
00851 #ifdef OS_VMS
00852
00853 return SS_SUCCESS;
00854
00855 #endif
00856 #ifdef OS_UNIX
00857
00858 if (!disable_shm_write) {
00859 FILE *fh;
00860
00861 fh = fopen(file_name, "w");
00862
00863 if (fh == NULL) {
00864 cm_msg(MERROR, "ss_shm_flush",
00865 "Cannot write to file %s, please check protection",
00866 file_name);
00867 } else {
00868
00869 fwrite(adr, 1, size, fh);
00870 fclose(fh);
00871 }
00872 }
00873 return SS_SUCCESS;
00874
00875 #endif
00876 }
00877
00878
00879 INT ss_getthandle(void)
00880
00881
00882
00883
00884
00885
00886
00887
00888
00889
00890
00891
00892
00893
00894
00895
00896 {
00897 #ifdef OS_WINNT
00898 HANDLE hThread;
00899
00900
00901
00902
00903
00904
00905
00906
00907
00908
00909 DuplicateHandle(GetCurrentProcess(), GetCurrentThread(),
00910 GetCurrentProcess(), &hThread, THREAD_ALL_ACCESS,
00911 TRUE, 0);
00912
00913 return (int) hThread;
00914
00915 #endif
00916 #ifdef OS_VMS
00917
00918 return 0;
00919
00920 #endif
00921 #ifdef OS_UNIX
00922
00923 return ss_getpid();
00924
00925 #endif
00926 }
00927
00928 #endif
00929
00930
00931 struct {
00932 char c;
00933 double d;
00934 } test_align;
00935
00936 INT ss_get_struct_align()
00937
00938
00939
00940
00941
00942
00943
00944
00945
00946
00947
00948
00949
00950
00951
00952
00953
00954
00955
00956
00957
00958 {
00959 return (PTYPE) (&test_align.d) - (PTYPE) & test_align.c;
00960 }
00961
00962
00963 INT ss_getpid(void)
00964
00965
00966
00967
00968
00969
00970
00971
00972
00973
00974
00975
00976
00977
00978
00979
00980 {
00981 #ifdef OS_WINNT
00982
00983 return (int) GetCurrentProcessId();
00984
00985 #endif
00986 #ifdef OS_VMS
00987
00988 return getpid();
00989
00990 #endif
00991 #ifdef OS_UNIX
00992
00993 return getpid();
00994
00995 #endif
00996 #ifdef OS_VXWORKS
00997
00998 return 0;
00999
01000 #endif
01001 #ifdef OS_MSDOS
01002
01003 return 0;
01004
01005 #endif
01006 }
01007
01008
01009
01010 static BOOL _single_thread = FALSE;
01011
01012 void ss_force_single_thread()
01013 {
01014 _single_thread = TRUE;
01015 }
01016
01017 INT ss_gettid(void)
01018
01019
01020
01021
01022
01023
01024
01025
01026
01027
01028
01029
01030
01031
01032
01033
01034 {
01035
01036 if (_single_thread)
01037 return 1;
01038
01039 #ifdef OS_MSDOS
01040
01041 return 0;
01042
01043 #endif
01044 #ifdef OS_WINNT
01045
01046 return (int) GetCurrentThreadId();
01047
01048 #endif
01049 #ifdef OS_VMS
01050
01051 return ss_getpid();
01052
01053 #endif
01054 #ifdef OS_UNIX
01055
01056 return ss_getpid();
01057
01058 #endif
01059 #ifdef OS_VXWORKS
01060
01061 return ss_getpid();
01062
01063 #endif
01064 }
01065
01066
01067
01068 #ifdef OS_UNIX
01069 void catch_sigchld(int signo)
01070 {
01071 int status;
01072
01073 wait(&status);
01074 return;
01075 }
01076 #endif
01077
01078 INT ss_spawnv(INT mode, char *cmdname, char *argv[])
01079
01080
01081
01082
01083
01084
01085
01086
01087
01088
01089
01090
01091
01092
01093
01094
01095
01096
01097
01098
01099
01100
01101 {
01102 #ifdef OS_WINNT
01103
01104 if (spawnvp(mode, cmdname, argv) < 0)
01105 return SS_INVALID_NAME;
01106
01107 return SS_SUCCESS;
01108
01109 #endif
01110
01111 #ifdef OS_MSDOS
01112
01113 spawnvp((int) mode, cmdname, argv);
01114
01115 return SS_SUCCESS;
01116
01117 #endif
01118
01119 #ifdef OS_VMS
01120
01121 {
01122 char cmdstring[500], *pc;
01123 INT i, flags, status;
01124 va_list argptr;
01125
01126 $DESCRIPTOR(cmdstring_dsc, "dummy");
01127
01128 if (mode & P_DETACH) {
01129 cmdstring_dsc.dsc$w_length = strlen(cmdstring);
01130 cmdstring_dsc.dsc$a_pointer = cmdstring;
01131
01132 status = sys$creprc(0, &cmdstring_dsc,
01133 0, 0, 0, 0, 0, NULL, 4, 0, 0, PRC$M_DETACH);
01134 } else {
01135 flags = (mode & P_NOWAIT) ? 1 : 0;
01136
01137 for (pc = argv[0] + strlen(argv[0]); *pc != ']' && pc != argv[0];
01138 pc--);
01139 if (*pc == ']')
01140 pc++;
01141
01142 strcpy(cmdstring, pc);
01143
01144 if (strchr(cmdstring, ';'))
01145 *strchr(cmdstring, ';') = 0;
01146
01147 strcat(cmdstring, " ");
01148
01149 for (i = 1; argv[i] != NULL; i++) {
01150 strcat(cmdstring, argv[i]);
01151 strcat(cmdstring, " ");
01152 }
01153
01154 cmdstring_dsc.dsc$w_length = strlen(cmdstring);
01155 cmdstring_dsc.dsc$a_pointer = cmdstring;
01156
01157 status = lib$spawn(&cmdstring_dsc, 0, 0, &flags, NULL,
01158 0, 0, 0, 0, 0, 0, 0, 0);
01159 }
01160
01161 return BM_SUCCESS;
01162 }
01163
01164 #endif
01165 #ifdef OS_UNIX
01166 pid_t child_pid;
01167
01168 #ifdef OS_ULTRIX
01169 union wait *status;
01170 #else
01171 int status;
01172 #endif
01173
01174 if ((child_pid = fork()) < 0)
01175 return (-1);
01176
01177 if (child_pid == 0) {
01178
01179 child_pid = execvp(cmdname, argv);
01180 return SS_SUCCESS;
01181 } else {
01182
01183 if (mode == P_WAIT)
01184 #ifdef OS_ULTRIX
01185 waitpid(child_pid, status, WNOHANG);
01186 #else
01187 waitpid(child_pid, &status, WNOHANG);
01188 #endif
01189
01190 else
01191
01192 signal(SIGCHLD, catch_sigchld);
01193 }
01194
01195 return SS_SUCCESS;
01196
01197 #endif
01198 }
01199
01200
01201 INT ss_shell(int sock)
01202
01203
01204
01205
01206
01207
01208
01209
01210
01211
01212
01213
01214
01215
01216
01217
01218 {
01219 #ifdef OS_WINNT
01220
01221 HANDLE hChildStdinRd, hChildStdinWr, hChildStdinWrDup,
01222 hChildStdoutRd, hChildStdoutWr,
01223 hChildStderrRd, hChildStderrWr, hSaveStdin, hSaveStdout, hSaveStderr;
01224
01225 SECURITY_ATTRIBUTES saAttr;
01226 PROCESS_INFORMATION piProcInfo;
01227 STARTUPINFO siStartInfo;
01228 char buffer[256], cmd[256];
01229 DWORD dwRead, dwWritten, dwAvail, i, i_cmd;
01230 fd_set readfds;
01231 struct timeval timeout;
01232
01233
01234 saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
01235 saAttr.bInheritHandle = TRUE;
01236 saAttr.lpSecurityDescriptor = NULL;
01237
01238
01239 hSaveStdout = GetStdHandle(STD_OUTPUT_HANDLE);
01240
01241
01242 if (!CreatePipe(&hChildStdoutRd, &hChildStdoutWr, &saAttr, 0))
01243 return 0;
01244
01245
01246 if (!SetStdHandle(STD_OUTPUT_HANDLE, hChildStdoutWr))
01247 return 0;
01248
01249
01250
01251 hSaveStderr = GetStdHandle(STD_ERROR_HANDLE);
01252
01253
01254 if (!CreatePipe(&hChildStderrRd, &hChildStderrWr, &saAttr, 0))
01255 return 0;
01256
01257
01258 if (!SetStdHandle(STD_ERROR_HANDLE, hChildStderrWr))
01259 return 0;
01260
01261
01262
01263 hSaveStdin = GetStdHandle(STD_INPUT_HANDLE);
01264
01265
01266 if (!CreatePipe(&hChildStdinRd, &hChildStdinWr, &saAttr, 0))
01267 return 0;
01268
01269
01270 if (!SetStdHandle(STD_INPUT_HANDLE, hChildStdinRd))
01271 return 0;
01272
01273
01274 if (!DuplicateHandle(GetCurrentProcess(), hChildStdinWr, GetCurrentProcess(), &hChildStdinWrDup, 0, FALSE,
01275 DUPLICATE_SAME_ACCESS))
01276 return 0;
01277
01278 CloseHandle(hChildStdinWr);
01279
01280
01281 memset(&siStartInfo, 0, sizeof(siStartInfo));
01282 siStartInfo.cb = sizeof(STARTUPINFO);
01283 siStartInfo.lpReserved = NULL;
01284 siStartInfo.lpReserved2 = NULL;
01285 siStartInfo.cbReserved2 = 0;
01286 siStartInfo.lpDesktop = NULL;
01287 siStartInfo.dwFlags = 0;
01288
01289 if (!CreateProcess(NULL, "cmd /Q",
01290 NULL,
01291 NULL,
01292 TRUE,
01293 0,
01294 NULL,
01295 NULL,
01296 &siStartInfo,
01297 &piProcInfo))
01298 return 0;
01299
01300
01301 SetStdHandle(STD_INPUT_HANDLE, hSaveStdin);
01302 SetStdHandle(STD_OUTPUT_HANDLE, hSaveStdout);
01303 SetStdHandle(STD_ERROR_HANDLE, hSaveStderr);
01304
01305 i_cmd = 0;
01306
01307 do {
01308
01309 do {
01310 if (!PeekNamedPipe
01311 (hChildStderrRd, buffer, 256, &dwRead, &dwAvail, NULL))
01312 break;
01313
01314 if (dwRead > 0) {
01315 ReadFile(hChildStderrRd, buffer, 256, &dwRead, NULL);
01316 send(sock, buffer, dwRead, 0);
01317 }
01318 } while (dwAvail > 0);
01319
01320
01321 do {
01322 if (!PeekNamedPipe
01323 (hChildStdoutRd, buffer, 256, &dwRead, &dwAvail, NULL))
01324 break;
01325 if (dwRead > 0) {
01326 ReadFile(hChildStdoutRd, buffer, 256, &dwRead, NULL);
01327 send(sock, buffer, dwRead, 0);
01328 }
01329 } while (dwAvail > 0);
01330
01331
01332
01333 if (!GetExitCodeProcess(piProcInfo.hProcess, &i))
01334 break;
01335 if (i != STILL_ACTIVE)
01336 break;
01337
01338
01339 FD_ZERO(&readfds);
01340 FD_SET(sock, &readfds);
01341 timeout.tv_sec = 0;
01342 timeout.tv_usec = 100;
01343 select(FD_SETSIZE, &readfds, NULL, NULL, &timeout);
01344
01345 if (FD_ISSET(sock, &readfds)) {
01346 i = recv(sock, cmd + i_cmd, 1, 0);
01347 if (i <= 0)
01348 break;
01349
01350
01351 if (cmd[i_cmd] == 8) {
01352 if (i_cmd > 0) {
01353 send(sock, "\b \b", 3, 0);
01354 i_cmd -= 1;
01355 }
01356 } else if (cmd[i_cmd] >= ' ' || cmd[i_cmd] == 13 || cmd[i_cmd] == 10) {
01357 send(sock, cmd + i_cmd, 1, 0);
01358 i_cmd += i;
01359 }
01360 }
01361
01362
01363 if (cmd[i_cmd - 1] == 10) {
01364 WriteFile(hChildStdinWrDup, cmd, i_cmd, &dwWritten, NULL);
01365 i_cmd = 0;
01366 }
01367
01368 } while (TRUE);
01369
01370 CloseHandle(hChildStdinWrDup);
01371 CloseHandle(hChildStdinRd);
01372 CloseHandle(hChildStderrRd);
01373 CloseHandle(hChildStdoutRd);
01374
01375 return SS_SUCCESS;
01376
01377 #endif
01378
01379 #ifdef OS_UNIX
01380 #ifndef NO_PTY
01381 pid_t pid;
01382 int i, pipe;
01383 char line[32], buffer[1024], shell[32];
01384 fd_set readfds;
01385
01386 if ((pid = forkpty(&pipe, line, NULL, NULL)) < 0)
01387 return 0;
01388 else if (pid > 0) {
01389
01390
01391 do {
01392 FD_ZERO(&readfds);
01393 FD_SET(sock, &readfds);
01394 FD_SET(pipe, &readfds);
01395
01396 select(FD_SETSIZE, (void *) &readfds, NULL, NULL, NULL);
01397
01398 if (FD_ISSET(sock, &readfds)) {
01399 memset(buffer, 0, sizeof(buffer));
01400 i = recv(sock, buffer, sizeof(buffer), 0);
01401 if (i <= 0)
01402 break;
01403 if (write(pipe, buffer, i) != i)
01404 break;
01405 }
01406
01407 if (FD_ISSET(pipe, &readfds)) {
01408 memset(buffer, 0, sizeof(buffer));
01409 i = read(pipe, buffer, sizeof(buffer));
01410 if (i <= 0)
01411 break;
01412 send(sock, buffer, i, 0);
01413 }
01414
01415 } while (1);
01416 } else {
01417
01418
01419 if (getenv("SHELL"))
01420 strlcpy(shell, getenv("SHELL"), sizeof(shell));
01421 else
01422 strcpy(shell, "/bin/sh");
01423 execl(shell, shell, 0);
01424 }
01425 #else
01426 send(sock, "not implemented\n", 17, 0);
01427 #endif
01428
01429 return SS_SUCCESS;
01430
01431 #endif
01432 }
01433
01434
01435 static BOOL _daemon_flag;
01436
01437 INT ss_daemon_init(BOOL keep_stdout)
01438
01439
01440
01441
01442
01443
01444
01445
01446
01447
01448
01449
01450
01451
01452
01453
01454
01455 {
01456 #ifdef OS_UNIX
01457
01458
01459 int i, fd, pid;
01460
01461 if ((pid = fork()) < 0)
01462 return SS_ABORT;
01463 else if (pid != 0)
01464 exit(0);
01465
01466
01467
01468 _daemon_flag = TRUE;
01469
01470
01471
01472 for (i = 0; i < 3; i++) {
01473 if (keep_stdout && ((i == 1) || (i == 2)))
01474 continue;
01475
01476 close(i);
01477 fd = open("/dev/null", O_RDWR, 0);
01478 if (fd < 0)
01479 fd = open("/dev/null", O_WRONLY, 0);
01480 if (fd < 0) {
01481 cm_msg(MERROR, "ss_system", "Can't open /dev/null");
01482 return SS_ABORT;
01483 }
01484 if (fd != i) {
01485 cm_msg(MERROR, "ss_system", "Did not get file descriptor");
01486 return SS_ABORT;
01487 }
01488 }
01489
01490 setsid();
01491 chdir("/");
01492 umask(0);
01493
01494 #endif
01495
01496 return SS_SUCCESS;
01497 }
01498
01499
01500 BOOL ss_existpid(INT pid)
01501
01502
01503
01504
01505
01506
01507
01508
01509
01510
01511
01512
01513
01514
01515
01516
01517
01518 {
01519 #ifdef OS_UNIX
01520
01521 return (kill(pid, 0) == 0 ? TRUE : FALSE);
01522 #else
01523 cm_msg(MINFO, "ss_existpid", "implemented for UNIX only");
01524 return FALSE;
01525 #endif
01526 }
01527
01528
01529
01530 #endif
01531
01532
01533
01534
01535
01536
01537
01538
01539
01540
01541
01542
01543
01544
01545
01546
01547
01548
01549
01550 INT ss_system(char *command)
01551 {
01552 #ifdef OS_UNIX
01553 INT childpid;
01554
01555 return ss_exec(command, &childpid);
01556
01557 #else
01558
01559 system(command);
01560 return SS_SUCCESS;
01561
01562 #endif
01563 }
01564
01565
01566 #ifndef DOXYGEN_SHOULD_SKIP_THIS
01567
01568
01569 INT ss_exec(char *command, INT * pid)
01570
01571
01572
01573
01574
01575
01576
01577
01578
01579
01580
01581
01582
01583
01584
01585
01586
01587
01588 {
01589 #ifdef OS_UNIX
01590
01591
01592 int i, fd;
01593
01594 if ((*pid = fork()) < 0)
01595 return SS_ABORT;
01596 else if (*pid != 0) {
01597
01598 signal(SIGCHLD, catch_sigchld);
01599 return SS_SUCCESS;
01600 }
01601
01602
01603
01604
01605 for (i = 0; i < 256; i++)
01606 close(i);
01607
01608
01609
01610 for (i = 0; i < 3; i++) {
01611 fd = open("/dev/null", O_RDWR, 0);
01612 if (fd < 0)
01613 fd = open("/dev/null", O_WRONLY, 0);
01614 if (fd < 0) {
01615 cm_msg(MERROR, "ss_exec", "Can't open /dev/null");
01616 return SS_ABORT;
01617 }
01618 if (fd != i) {
01619 cm_msg(MERROR, "ss_exec", "Did not get file descriptor");
01620 return SS_ABORT;
01621 }
01622 }
01623
01624 setsid();
01625
01626 umask(0);
01627
01628
01629 execl("/bin/sh", "sh", "-c", command, NULL);
01630
01631 #else
01632
01633 system(command);
01634
01635 #endif
01636
01637 return SS_SUCCESS;
01638 }
01639
01640
01641 #endif
01642
01643
01644
01645
01646
01647
01648
01649
01650
01651
01652
01653
01654
01655
01656
01657
01658
01659
01660
01661
01662
01663
01664
01665
01666
01667
01668
01669
01670
01671
01672
01673
01674
01675
01676 INT ss_thread_create(INT(*thread_func) (void *), void *param)
01677 {
01678 #ifdef OS_WINNT
01679
01680 HANDLE status;
01681 DWORD thread_id;
01682
01683 if (thread_func == NULL) {
01684 return 0;
01685 }
01686
01687 status = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) thread_func,
01688 (LPVOID) param, 0, &thread_id);
01689
01690 return status == NULL ? 0 : thread_id;
01691
01692 #endif
01693 #ifdef OS_MSDOS
01694
01695 return 0;
01696
01697 #endif
01698 #ifdef OS_VMS
01699
01700 return 0;
01701
01702 #endif
01703
01704 #ifdef OS_VXWORKS
01705
01706
01707
01708
01709
01710
01711
01712 INT status;
01713 VX_TASK_SPAWN *ts;
01714
01715 ts = (VX_TASK_SPAWN *) param;
01716 status =
01717 taskSpawn(ts->name, ts->priority, ts->options, ts->stackSize,
01718 (FUNCPTR) thread_func, ts->arg1, ts->arg2, ts->arg3,
01719 ts->arg4, ts->arg5, ts->arg6, ts->arg7, ts->arg8, ts->arg9,
01720 ts->arg10);
01721
01722 return status == ERROR ? 0 : status;
01723 #endif
01724
01725 #ifdef OS_UNIX
01726 INT status;
01727 pthread_t thread_id;
01728
01729 status = pthread_create(&thread_id, NULL, (void *) thread_func, param);
01730
01731 return status != 0 ? 0 : thread_id;
01732 #endif
01733 }
01734
01735
01736
01737
01738
01739
01740
01741
01742
01743
01744
01745
01746
01747
01748
01749
01750
01751
01752
01753 INT ss_thread_kill(INT thread_id)
01754 {
01755 #ifdef OS_WINNT
01756
01757 DWORD status;
01758
01759 status = TerminateThread((HANDLE) thread_id, 0);
01760
01761 return status != 0 ? SS_SUCCESS : SS_NO_THREAD;
01762
01763 #endif
01764 #ifdef OS_MSDOS
01765
01766 return 0;
01767
01768 #endif
01769 #ifdef OS_VMS
01770
01771 return 0;
01772
01773 #endif
01774
01775 #ifdef OS_VXWORKS
01776 INT status;
01777
01778 status = taskDelete(thread_id);
01779
01780 return status == OK ? 0 : ERROR;
01781 #endif
01782
01783 #ifdef OS_UNIX
01784 INT status;
01785
01786 status = pthread_kill((pthread_t) thread_id, SIGKILL);
01787
01788 return status == 0 ? SS_SUCCESS : SS_NO_THREAD;
01789 #endif
01790 }
01791
01792
01793 #ifndef DOXYGEN_SHOULD_SKIP_THIS
01794
01795
01796 static INT skip_mutex_handle = -1;
01797
01798 INT ss_mutex_create(char *name, HNDLE * mutex_handle)
01799
01800
01801
01802
01803
01804
01805
01806
01807
01808
01809
01810
01811
01812
01813
01814
01815
01816
01817
01818
01819
01820
01821
01822
01823
01824
01825 {
01826 char mutex_name[256], path[256], file_name[256];
01827
01828
01829 sprintf(mutex_name, "MX_%s", name);
01830
01831 #ifdef OS_VXWORKS
01832
01833
01834
01835 if ((*((SEM_ID *) mutex_handle) =
01836 semBCreate(SEM_Q_FIFO, SEM_EMPTY)) == NULL)
01837 return SS_NO_MUTEX;
01838 return SS_CREATED;
01839
01840 #endif
01841
01842
01843 cm_get_path(path);
01844 if (path[0] == 0) {
01845 getcwd(path, 256);
01846 #if defined(OS_VMS)
01847 #elif defined(OS_UNIX)
01848 strcat(path, "/");
01849 #elif defined(OS_WINNT)
01850 strcat(path, "\\");
01851 #endif
01852 }
01853
01854 strcpy(file_name, path);
01855 #if defined (OS_UNIX)
01856 strcat(file_name, ".");
01857 #endif
01858 strcat(file_name, name);
01859 strcat(file_name, ".SHM");
01860
01861 #ifdef OS_WINNT
01862
01863 *mutex_handle = (HNDLE) CreateMutex(NULL, FALSE, mutex_name);
01864
01865 if (*mutex_handle == 0)
01866 return SS_NO_MUTEX;
01867
01868 return SS_CREATED;
01869
01870 #endif
01871 #ifdef OS_VMS
01872
01873
01874
01875 {
01876 INT status;
01877 $DESCRIPTOR(mutexname_dsc, "dummy");
01878 mutexname_dsc.dsc$w_length = strlen(mutex_name);
01879 mutexname_dsc.dsc$a_pointer = mutex_name;
01880
01881 *mutex_handle = (HNDLE) malloc(8);
01882
01883 status = sys$enqw(0, LCK$K_NLMODE, *mutex_handle, 0, &mutexname_dsc,
01884 0, 0, 0, 0, 0, 0);
01885
01886 if (status != SS$_NORMAL) {
01887 free((void *) *mutex_handle);
01888 *mutex_handle = 0;
01889 }
01890
01891 if (*mutex_handle == 0)
01892 return SS_NO_MUTEX;
01893
01894 return SS_CREATED;
01895 }
01896
01897 #endif
01898 #ifdef OS_UNIX
01899
01900 {
01901 INT key, status, fh;
01902 struct semid_ds buf;
01903
01904 #if (defined(OS_LINUX) && !defined(_SEM_SEMUN_UNDEFINED)) || defined(OS_FREEBSD)
01905 union semun arg;
01906 #else
01907 union semun {
01908 INT val;
01909 struct semid_ds *buf;
01910 ushort *array;
01911 } arg;
01912 #endif
01913
01914 status = SS_SUCCESS;
01915
01916
01917 key = ftok(file_name, 'M');
01918 if (key < 0) {
01919 fh = open(file_name, O_CREAT, 0644);
01920 close(fh);
01921 key = ftok(file_name, 'M');
01922 status = SS_CREATED;
01923 }
01924
01925
01926 *mutex_handle = (HNDLE) semget(key, 1, 0);
01927 if (*mutex_handle < 0) {
01928 *mutex_handle = (HNDLE) semget(key, 1, IPC_CREAT);
01929 status = SS_CREATED;
01930 }
01931
01932 if (*mutex_handle < 0) {
01933 cm_msg(MERROR, "ss_mutex_mutex", "semget() failed, errno = %d",
01934 errno);
01935 return SS_NO_MUTEX;
01936 }
01937
01938 buf.sem_perm.uid = getuid();
01939 buf.sem_perm.gid = getgid();
01940 buf.sem_perm.mode = 0666;
01941 arg.buf = &buf;
01942
01943 semctl(*mutex_handle, 0, IPC_SET, arg);
01944
01945
01946 if (status == SS_CREATED) {
01947 arg.val = 1;
01948 if (semctl(*mutex_handle, 0, SETVAL, arg) < 0)
01949 return SS_NO_MUTEX;
01950 }
01951
01952 return SS_SUCCESS;
01953 }
01954 #endif
01955
01956 #ifdef OS_MSDOS
01957 return SS_NO_MUTEX;
01958 #endif
01959 }
01960
01961
01962 INT ss_mutex_wait_for(HNDLE mutex_handle, INT timeout)
01963
01964
01965
01966
01967
01968
01969
01970
01971
01972
01973
01974
01975
01976
01977
01978
01979
01980
01981
01982 {
01983 INT status;
01984
01985 #ifdef OS_WINNT
01986
01987 status = WaitForSingleObject((HANDLE) mutex_handle,
01988 timeout == 0 ? INFINITE : timeout);
01989 if (status == WAIT_FAILED)
01990 return SS_NO_MUTEX;
01991 if (status == WAIT_TIMEOUT)
01992 return SS_TIMEOUT;
01993
01994 return SS_SUCCESS;
01995 #endif
01996 #ifdef OS_VMS
01997 status = sys$enqw(0, LCK$K_EXMODE, mutex_handle, LCK$M_CONVERT,
01998 0, 0, 0, 0, 0, 0, 0);
01999 if (status != SS$_NORMAL)
02000 return SS_NO_MUTEX;
02001 return SS_SUCCESS;
02002
02003 #endif
02004 #ifdef OS_VXWORKS
02005
02006 status =
02007 semTake((SEM_ID) mutex_handle,
02008 timeout == 0 ? WAIT_FOREVER : timeout >> 4);
02009 if (status == ERROR)
02010 return SS_NO_MUTEX;
02011 return SS_SUCCESS;
02012
02013 #endif
02014 #ifdef OS_UNIX
02015 {
02016 DWORD start_time;
02017 struct sembuf sb;
02018
02019 #if (defined(OS_LINUX) && !defined(_SEM_SEMUN_UNDEFINED)) || defined(OS_FREEBSD)
02020 union semun arg;
02021 #else
02022 union semun {
02023 INT val;
02024 struct semid_ds *buf;
02025 ushort *array;
02026 } arg;
02027 #endif
02028
02029 sb.sem_num = 0;
02030 sb.sem_op = -1;
02031 sb.sem_flg = SEM_UNDO;
02032
02033 memset(&arg, 0, sizeof(arg));
02034
02035
02036
02037 if (ss_in_async_routine_flag)
02038 if (semctl(mutex_handle, 0, GETPID, arg) == getpid())
02039 if (semctl(mutex_handle, 0, GETVAL, arg) == 0) {
02040 skip_mutex_handle = mutex_handle;
02041 return SS_SUCCESS;
02042 }
02043
02044 skip_mutex_handle = -1;
02045
02046 start_time = ss_millitime();
02047
02048 do {
02049 status = semop(mutex_handle, &sb, 1);
02050
02051
02052 if (status == 0)
02053 break;
02054
02055
02056 if (errno == EINTR) {
02057
02058 if (timeout > 0 && ss_millitime() - start_time > timeout)
02059 return SS_TIMEOUT;
02060
02061 continue;
02062 }
02063
02064 return SS_NO_MUTEX;
02065 } while (1);
02066
02067 return SS_SUCCESS;
02068 }
02069 #endif
02070
02071 #ifdef OS_MSDOS
02072 return SS_NO_MUTEX;
02073 #endif
02074 }
02075
02076
02077 INT ss_mutex_release(HNDLE mutex_handle)
02078
02079
02080
02081
02082
02083
02084
02085
02086
02087
02088
02089
02090
02091
02092
02093
02094
02095 {
02096 INT status;
02097
02098 #ifdef OS_WINNT
02099
02100 status = ReleaseMutex((HANDLE) mutex_handle);
02101
02102 if (status == FALSE)
02103 return SS_NO_MUTEX;
02104
02105 return SS_SUCCESS;
02106
02107 #endif
02108 #ifdef OS_VMS
02109
02110 status =
02111 sys$enqw(0, LCK$K_NLMODE, mutex_handle, LCK$M_CONVERT, 0, 0, 0, 0, 0,
02112 0, 0);
02113
02114 if (status != SS$_NORMAL)
02115 return SS_NO_MUTEX;
02116
02117 return SS_SUCCESS;
02118
02119 #endif
02120
02121 #ifdef OS_VXWORKS
02122
02123 if (semGive((SEM_ID) mutex_handle) == ERROR)
02124 return SS_NO_MUTEX;
02125 return SS_SUCCESS;
02126 #endif
02127
02128 #ifdef OS_UNIX
02129 {
02130 struct sembuf sb;
02131
02132 sb.sem_num = 0;
02133 sb.sem_op = 1;
02134 sb.sem_flg = SEM_UNDO;
02135
02136 if (mutex_handle == skip_mutex_handle) {
02137 skip_mutex_handle = -1;
02138 return SS_SUCCESS;
02139 }
02140
02141 do {
02142 status = semop(mutex_handle, &sb, 1);
02143
02144
02145 if (status == 0)
02146 break;
02147
02148
02149 if (errno == EINTR)
02150 continue;
02151
02152 return SS_NO_MUTEX;
02153 } while (1);
02154
02155 return SS_SUCCESS;
02156 }
02157 #endif
02158
02159 #ifdef OS_MSDOS
02160 return SS_NO_MUTEX;
02161 #endif
02162 }
02163
02164
02165 INT ss_mutex_delete(HNDLE mutex_handle, INT destroy_flag)
02166
02167
02168
02169
02170
02171
02172
02173
02174
02175
02176
02177
02178
02179
02180
02181
02182
02183 {
02184 #ifdef OS_WINNT
02185
02186 if (CloseHandle((HANDLE) mutex_handle) == FALSE)
02187 return SS_NO_MUTEX;
02188
02189 return SS_SUCCESS;
02190
02191 #endif
02192 #ifdef OS_VMS
02193
02194 free((void *) mutex_handle);
02195 return SS_SUCCESS;
02196
02197 #endif
02198
02199 #ifdef OS_VXWORKS
02200
02201 if (semDelete((SEM_ID) mutex_handle) == ERROR)
02202 return SS_NO_MUTEX;
02203 return SS_SUCCESS;
02204 #endif
02205
02206 #ifdef OS_UNIX
02207 #if (defined(OS_LINUX) && !defined(_SEM_SEMUN_UNDEFINED)) || defined(OS_FREEBSD)
02208 union semun arg;
02209 #else
02210 union semun {
02211 INT val;
02212 struct semid_ds *buf;
02213 ushort *array;
02214 } arg;
02215 #endif
02216
02217 memset(&arg, 0, sizeof(arg));
02218
02219 if (destroy_flag)
02220 if (semctl(mutex_handle, 0, IPC_RMID, arg) < 0)
02221 return SS_NO_MUTEX;
02222
02223 return SS_SUCCESS;
02224
02225 #endif
02226
02227 #ifdef OS_MSDOS
02228 return SS_NO_MUTEX;
02229 #endif
02230 }
02231
02232
02233 #endif
02234
02235
02236
02237
02238
02239
02240
02241
02242
02243
02244
02245
02246
02247
02248
02249
02250
02251
02252
02253 DWORD ss_millitime()
02254 {
02255 #ifdef OS_WINNT
02256
02257 return (int) GetTickCount();
02258
02259 #endif
02260 #ifdef OS_MSDOS
02261
02262 return clock() * 55;
02263
02264 #endif
02265 #ifdef OS_VMS
02266
02267 {
02268 char time[8];
02269 DWORD lo, hi;
02270
02271 sys$gettim(time);
02272
02273 lo = *((DWORD *) time);
02274 hi = *((DWORD *) (time + 4));
02275
02276
02277
02278 return lo / 10000 + hi * 429496.7296;
02279
02280 }
02281
02282 #endif
02283 #ifdef OS_UNIX
02284 {
02285 struct timeval tv;
02286
02287 gettimeofday(&tv, NULL);
02288
02289 return tv.tv_sec * 1000 + tv.tv_usec / 1000;
02290 }
02291
02292 #endif
02293 #ifdef OS_VXWORKS
02294 {
02295 int count;
02296 static int ticks_per_msec = 0;
02297
02298 if (ticks_per_msec == 0)
02299 ticks_per_msec = 1000 / sysClkRateGet();
02300
02301 return tickGet() * ticks_per_msec;
02302 }
02303 #endif
02304 }
02305
02306
02307
02308
02309
02310
02311
02312
02313
02314
02315
02316
02317
02318
02319
02320 DWORD ss_time()
02321 {
02322 #if !defined(OS_VXWORKS)
02323 #if !defined(OS_VMS)
02324 tzset();
02325 #endif
02326 #endif
02327 return (DWORD) time(NULL);
02328 }
02329
02330
02331 #ifndef DOXYGEN_SHOULD_SKIP_THIS
02332
02333
02334 DWORD ss_settime(DWORD seconds)
02335
02336
02337
02338
02339
02340
02341
02342
02343
02344
02345
02346
02347
02348
02349
02350 {
02351 #ifdef OS_WINNT
02352 SYSTEMTIME st;
02353 struct tm *ltm;
02354
02355 tzset();
02356 ltm = localtime((time_t *) & seconds);
02357
02358 st.wYear = ltm->tm_year + 1900;
02359 st.wMonth = ltm->tm_mon + 1;
02360 st.wDay = ltm->tm_mday;
02361 st.wHour = ltm->tm_hour;
02362 st.wMinute = ltm->tm_min;
02363 st.wSecond = ltm->tm_sec;
02364 st.wMilliseconds = 0;
02365
02366 SetLocalTime(&st);
02367
02368 #endif
02369 #ifdef OS_UNIX
02370
02371 stime((time_t *) & seconds);
02372
02373 #endif
02374 #ifdef OS_VXWORKS
02375
02376 struct timespec ltm;
02377
02378 ltm.tv_sec = seconds;
02379 ltm.tv_nsec = 0;
02380 clock_settime(CLOCK_REALTIME, <m);
02381
02382 #endif
02383 return SS_SUCCESS;
02384 }
02385
02386
02387 char *ss_asctime()
02388
02389
02390
02391
02392
02393
02394
02395
02396
02397
02398
02399
02400
02401
02402
02403
02404 {
02405 static char str[32];
02406 time_t seconds;
02407
02408 seconds = (time_t) ss_time();
02409
02410 #if !defined(OS_VXWORKS)
02411 #if !defined(OS_VMS)
02412 tzset();
02413 #endif
02414 #endif
02415 strcpy(str, asctime(localtime(&seconds)));
02416
02417
02418 str[24] = 0;
02419
02420 return str;
02421 }
02422
02423
02424
02425 #ifdef OS_UNIX
02426
02427 void ss_cont()
02428 {
02429 }
02430 #endif
02431
02432
02433 #endif
02434
02435
02436
02437
02438
02439
02440
02441
02442
02443
02444
02445
02446
02447 INT ss_sleep(INT millisec)
02448 {
02449 fd_set readfds;
02450 struct timeval timeout;
02451 int status;
02452 static int sock = 0;
02453
02454 if (millisec == 0) {
02455 #ifdef OS_WINNT
02456 SuspendThread(GetCurrentThread());
02457 #endif
02458 #ifdef OS_VMS
02459 sys$hiber();
02460 #endif
02461 #ifdef OS_UNIX
02462 signal(SIGCONT, ss_cont);
02463 pause();
02464 #endif
02465 return SS_SUCCESS;
02466 }
02467 #ifdef OS_WINNT
02468 {
02469 WSADATA WSAData;
02470
02471
02472 if (WSAStartup(MAKEWORD(1, 1), &WSAData) != 0)
02473 return SS_SOCKET_ERROR;
02474 }
02475 #endif
02476
02477 timeout.tv_sec = millisec / 1000;
02478 timeout.tv_usec = (millisec % 1000) * 1000;
02479
02480 if (!sock)
02481 sock = socket(AF_INET, SOCK_DGRAM, 0);
02482
02483 FD_ZERO(&readfds);
02484 FD_SET(sock, &readfds);
02485 do {
02486 status = select(FD_SETSIZE, &readfds, NULL, NULL, &timeout);
02487
02488
02489 if (status == -1 && timeout.tv_sec >= WATCHDOG_INTERVAL / 1000)
02490 timeout.tv_sec -= WATCHDOG_INTERVAL / 1000;
02491
02492 } while (status == -1);
02493
02494 return SS_SUCCESS;
02495 }
02496
02497
02498 #ifndef DOXYGEN_SHOULD_SKIP_THIS
02499
02500
02501 BOOL ss_kbhit()
02502
02503
02504
02505
02506
02507
02508
02509
02510
02511
02512
02513
02514
02515
02516
02517
02518
02519 {
02520 #ifdef OS_MSDOS
02521
02522 return kbhit();
02523
02524 #endif
02525 #ifdef OS_WINNT
02526
02527 return kbhit();
02528
02529 #endif
02530 #ifdef OS_VMS
02531
02532 return FALSE;
02533
02534 #endif
02535 #ifdef OS_UNIX
02536
02537 int n;
02538
02539 if (_daemon_flag)
02540 return 0;
02541
02542 ioctl(0, FIONREAD, &n);
02543 return (n > 0);
02544
02545 #endif
02546 #ifdef OS_VXWORKS
02547
02548 int n;
02549 ioctl(0, FIONREAD, (long) &n);
02550 return (n > 0);
02551
02552 #endif
02553 }
02554
02555
02556
02557 #ifdef LOCAL_ROUTINES
02558
02559 INT ss_wake(INT pid, INT tid, INT thandle)
02560
02561
02562
02563
02564
02565
02566
02567
02568
02569
02570
02571
02572
02573
02574
02575
02576
02577
02578
02579
02580
02581 {
02582 #ifdef OS_WINNT
02583 HANDLE process_handle;
02584 HANDLE dup_thread_handle;
02585
02586
02587
02588
02589
02590
02591
02592
02593
02594
02595 process_handle = OpenProcess(PROCESS_ALL_ACCESS, TRUE, pid);
02596
02597 if (process_handle == 0)
02598 return SS_NO_PROCESS;
02599
02600 DuplicateHandle(process_handle, (HANDLE) thandle, GetCurrentProcess(),
02601 &dup_thread_handle, THREAD_ALL_ACCESS, TRUE, 0);
02602
02603
02604 CloseHandle(process_handle);
02605
02606 if (dup_thread_handle == 0)
02607 return SS_NO_PROCESS;
02608
02609 ResumeThread(dup_thread_handle);
02610
02611
02612 CloseHandle(dup_thread_handle);
02613
02614 return SS_SUCCESS;
02615
02616 #endif
02617 #ifdef OS_VMS
02618
02619 if (sys$wake(&pid, 0) == SS$_NONEXPR)
02620 return SS_NO_PROCESS;
02621
02622 return SS_SUCCESS;
02623
02624 #endif
02625 #ifdef OS_UNIX
02626
02627 if (kill(pid, SIGCONT) < 0)
02628 return SS_NO_PROCESS;
02629
02630 return SS_SUCCESS;
02631
02632
02633
02634
02635
02636
02637
02638
02639
02640 #endif
02641 }
02642
02643
02644 #ifdef OS_WINNT
02645
02646 static void (*UserCallback) (int);
02647 static UINT _timer_id = 0;
02648
02649 VOID CALLBACK _timeCallback(UINT idEvent, UINT uReserved, DWORD dwUser,
02650 DWORD dwReserved1, DWORD dwReserved2)
02651 {
02652 _timer_id = 0;
02653 if (UserCallback != NULL)
02654 UserCallback(0);
02655 }
02656
02657 #endif
02658
02659 INT ss_alarm(INT millitime, void (*func) (int))
02660
02661
02662
02663
02664
02665
02666
02667
02668
02669
02670
02671
02672
02673
02674
02675
02676
02677
02678
02679 {
02680 #ifdef OS_WINNT
02681
02682 UserCallback = func;
02683 if (millitime > 0)
02684 _timer_id =
02685 timeSetEvent(millitime, 100, (LPTIMECALLBACK) _timeCallback, 0,
02686 TIME_ONESHOT);
02687 else {
02688 if (_timer_id)
02689 timeKillEvent(_timer_id);
02690 _timer_id = 0;
02691 }
02692
02693 return SS_SUCCESS;
02694
02695 #endif
02696 #ifdef OS_VMS
02697
02698 signal(SIGALRM, func);
02699 alarm(millitime / 1000);
02700 return SS_SUCCESS;
02701
02702 #endif
02703 #ifdef OS_UNIX
02704
02705 signal(SIGALRM, func);
02706 alarm(millitime / 1000);
02707 return SS_SUCCESS;
02708
02709 #endif
02710 }
02711
02712
02713 void (*MidasExceptionHandler) ();
02714
02715 #ifdef OS_WINNT
02716
02717 LONG MidasExceptionFilter(LPEXCEPTION_POINTERS pexcep)
02718 {
02719 if (MidasExceptionHandler != NULL)
02720 MidasExceptionHandler();
02721
02722 return EXCEPTION_CONTINUE_SEARCH;
02723 }
02724
02725 INT MidasExceptionSignal(INT sig)
02726 {
02727 if (MidasExceptionHandler != NULL)
02728 MidasExceptionHandler();
02729
02730 raise(sig);
02731
02732 return 0;
02733 }
02734
02735
02736
02737
02738
02739
02740
02741
02742
02743
02744
02745 #endif
02746
02747 #ifdef OS_VMS
02748
02749 INT MidasExceptionFilter(INT * sigargs, INT * mechargs)
02750 {
02751 if (MidasExceptionHandler != NULL)
02752 MidasExceptionHandler();
02753
02754 return (SS$_RESIGNAL);
02755 }
02756
02757 void MidasExceptionSignal(INT sig)
02758 {
02759 if (MidasExceptionHandler != NULL)
02760 MidasExceptionHandler();
02761
02762 kill(getpid(), sig);
02763 }
02764
02765 #endif
02766
02767
02768 INT ss_exception_handler(void (*func) ())
02769
02770
02771
02772
02773
02774
02775
02776
02777
02778
02779
02780
02781
02782
02783
02784
02785
02786
02787 {
02788 #ifdef OS_WINNT
02789
02790 MidasExceptionHandler = func;
02791
02792
02793
02794
02795
02796
02797
02798
02799
02800
02801
02802 #endif
02803 #ifdef OS_VMS
02804
02805 MidasExceptionHandler = func;
02806 lib$establish(MidasExceptionFilter);
02807
02808 signal(SIGINT, MidasExceptionSignal);
02809 signal(SIGILL, MidasExceptionSignal);
02810 signal(SIGQUIT, MidasExceptionSignal);
02811 signal(SIGFPE, MidasExceptionSignal);
02812 signal(SIGSEGV, MidasExceptionSignal);
02813 signal(SIGTERM, MidasExceptionSignal);
02814
02815 #endif
02816
02817 return SS_SUCCESS;
02818 }
02819
02820 #endif
02821
02822
02823 void *ss_ctrlc_handler(void (*func) (int))
02824
02825
02826
02827
02828
02829
02830
02831
02832
02833
02834
02835
02836
02837
02838
02839
02840
02841
02842
02843 {
02844 #ifdef OS_WINNT
02845
02846 if (func == NULL) {
02847 signal(SIGBREAK, SIG_DFL);
02848 return signal(SIGINT, SIG_DFL);
02849 } else {
02850 signal(SIGBREAK, func);
02851 return signal(SIGINT, func);
02852 }
02853 return NULL;
02854
02855 #endif
02856 #ifdef OS_VMS
02857
02858 return signal(SIGINT, func);
02859
02860 #endif
02861
02862 #ifdef OS_UNIX
02863
02864 if (func == NULL) {
02865 signal(SIGTERM, SIG_DFL);
02866 return (void *) signal(SIGINT, SIG_DFL);
02867 } else {
02868 signal(SIGTERM, func);
02869 return (void *) signal(SIGINT, func);
02870 }
02871
02872 #endif
02873 }
02874
02875
02876
02877
02878
02879
02880
02881
02882
02883
02884
02885
02886
02887
02888
02889
02890
02891
02892
02893 typedef struct {
02894 BOOL in_use;
02895 INT thread_id;
02896 INT ipc_port;
02897 INT ipc_recv_socket;
02898 INT ipc_send_socket;
02899 INT(*ipc_dispatch) (char *, INT);
02900 INT listen_socket;
02901 INT(*listen_dispatch) (INT);
02902 RPC_SERVER_CONNECTION *server_connection;
02903 INT(*client_dispatch) (INT);
02904 RPC_SERVER_ACCEPTION *server_acception;
02905 INT(*server_dispatch) (INT, int, BOOL);
02906 struct sockaddr_in bind_addr;
02907 } SUSPEND_STRUCT;
02908
02909 SUSPEND_STRUCT *_suspend_struct = NULL;
02910 INT _suspend_entries;
02911
02912
02913 INT ss_suspend_init_ipc(INT index)
02914
02915
02916
02917
02918
02919
02920
02921
02922
02923
02924
02925
02926
02927
02928
02929
02930
02931
02932 {
02933 INT status, sock;
02934 int i;
02935 struct sockaddr_in bind_addr;
02936 char local_host_name[HOST_NAME_LENGTH];
02937 struct hostent *phe;
02938
02939 #ifdef OS_WINNT
02940 {
02941 WSADATA WSAData;
02942
02943
02944 if (WSAStartup(MAKEWORD(1, 1), &WSAData) != 0)
02945 return SS_SOCKET_ERROR;
02946 }
02947 #endif
02948
02949
02950 sock = socket(AF_INET, SOCK_DGRAM, 0);
02951 if (sock == -1)
02952 return SS_SOCKET_ERROR;
02953
02954
02955 memset(&bind_addr, 0, sizeof(bind_addr));
02956 bind_addr.sin_family = AF_INET;
02957 bind_addr.sin_addr.s_addr = 0;
02958 bind_addr.sin_port = 0;
02959
02960 gethostname(local_host_name, sizeof(local_host_name));
02961
02962 #ifdef OS_VXWORKS
02963 {
02964 INT host_addr;
02965
02966 host_addr = hostGetByName(local_host_name);
02967 memcpy((char *) &(bind_addr.sin_addr), &host_addr, 4);
02968 }
02969 #else
02970 phe = gethostbyname(local_host_name);
02971 if (phe == NULL) {
02972 cm_msg(MERROR, "ss_suspend_init_ipc", "cannot get host name");
02973 return SS_SOCKET_ERROR;
02974 }
02975 memcpy((char *) &(bind_addr.sin_addr), phe->h_addr, phe->h_length);
02976 #endif
02977
02978 status = bind(sock, (struct sockaddr *) &bind_addr, sizeof(bind_addr));
02979 if (status < 0)
02980 return SS_SOCKET_ERROR;
02981
02982
02983 i = sizeof(bind_addr);
02984 getsockname(sock, (struct sockaddr *) &bind_addr, (int *) &i);
02985
02986 _suspend_struct[index].ipc_recv_socket = sock;
02987 _suspend_struct[index].ipc_port = ntohs(bind_addr.sin_port);
02988
02989
02990 sock = socket(AF_INET, SOCK_DGRAM, 0);
02991
02992 if (sock == -1)
02993 return SS_SOCKET_ERROR;
02994
02995
02996 memset(&bind_addr, 0, sizeof(bind_addr));
02997 bind_addr.sin_family = AF_INET;
02998 bind_addr.sin_addr.s_addr = 0;
02999
03000 #ifdef OS_VXWORKS
03001 {
03002 INT host_addr;
03003
03004 host_addr = hostGetByName(local_host_name);
03005 memcpy((char *) &(bind_addr.sin_addr), &host_addr, 4);
03006 }
03007 #else
03008 memcpy((char *) &(bind_addr.sin_addr), phe->h_addr, phe->h_length);
03009 #endif
03010
03011 memcpy(&_suspend_struct[index].bind_addr, &bind_addr, sizeof(bind_addr));
03012 _suspend_struct[index].ipc_send_socket = sock;
03013
03014 return SS_SUCCESS;
03015 }
03016
03017
03018 INT ss_suspend_get_index(INT * pindex)
03019
03020
03021
03022
03023
03024
03025
03026
03027
03028
03029
03030
03031
03032
03033
03034
03035
03036
03037
03038 {
03039 INT index;
03040
03041 if (_suspend_struct == NULL) {
03042
03043 _suspend_struct = (SUSPEND_STRUCT *) malloc(sizeof(SUSPEND_STRUCT));
03044 memset(_suspend_struct, 0, sizeof(SUSPEND_STRUCT));
03045 if (_suspend_struct == NULL)
03046 return SS_NO_MEMORY;
03047
03048 _suspend_entries = 1;
03049 *pindex = 0;
03050 _suspend_struct[0].thread_id = ss_gettid();
03051 _suspend_struct[0].in_use = TRUE;
03052 } else {
03053
03054 for (index = 0; index < _suspend_entries; index++)
03055 if (_suspend_struct[index].thread_id == ss_gettid()) {
03056 if (pindex != NULL)
03057 *pindex = index;
03058
03059 return SS_SUCCESS;
03060 }
03061
03062
03063 for (index = 0; index < _suspend_entries; index++)
03064 if (!_suspend_struct[index].in_use)
03065 break;
03066
03067 if (index == _suspend_entries) {
03068
03069 _suspend_struct = (SUSPEND_STRUCT *) realloc(_suspend_struct,
03070 sizeof(SUSPEND_STRUCT) *
03071 (_suspend_entries + 1));
03072 memset(&_suspend_struct[_suspend_entries], 0,
03073 sizeof(SUSPEND_STRUCT));
03074
03075 _suspend_entries++;
03076 if (_suspend_struct == NULL) {
03077 _suspend_entries--;
03078 return SS_NO_MEMORY;
03079 }
03080 }
03081 *pindex = index;
03082 _suspend_struct[index].thread_id = ss_gettid();
03083 _suspend_struct[index].in_use = TRUE;
03084 }
03085
03086 return SS_SUCCESS;
03087 }
03088
03089
03090 INT ss_suspend_exit()
03091
03092
03093
03094
03095
03096
03097
03098
03099
03100
03101
03102
03103
03104
03105
03106
03107
03108 {
03109 INT i, status;
03110
03111 status = ss_suspend_get_index(&i);
03112
03113 if (status != SS_SUCCESS)
03114 return status;
03115
03116 if (_suspend_struct[i].ipc_recv_socket) {
03117 closesocket(_suspend_struct[i].ipc_recv_socket);
03118 closesocket(_suspend_struct[i].ipc_send_socket);
03119 }
03120
03121 memset(&_suspend_struct[i], 0, sizeof(SUSPEND_STRUCT));
03122
03123
03124 for (i = _suspend_entries - 1; i >= 0; i--)
03125 if (_suspend_struct[i].in_use)
03126 break;
03127
03128 _suspend_entries = i + 1;
03129
03130 if (_suspend_entries == 0) {
03131 free(_suspend_struct);
03132 _suspend_struct = NULL;
03133 }
03134
03135 return SS_SUCCESS;
03136 }
03137
03138
03139 INT ss_suspend_set_dispatch(INT channel, void *connection,
03140 INT(*dispatch) ())
03141
03142
03143
03144
03145
03146
03147
03148
03149
03150
03151
03152
03153
03154
03155
03156
03157
03158
03159
03160
03161
03162
03163
03164
03165
03166
03167
03168
03169 {
03170 INT i, status;
03171
03172 status = ss_suspend_get_index(&i);
03173
03174 if (status != SS_SUCCESS)
03175 return status;
03176
03177 if (channel == CH_IPC) {
03178 _suspend_struct[i].ipc_dispatch = (INT(*)(char *, INT)) dispatch;
03179
03180 if (!_suspend_struct[i].ipc_recv_socket)
03181 ss_suspend_init_ipc(i);
03182 }
03183
03184 if (channel == CH_LISTEN) {
03185 _suspend_struct[i].listen_socket = *((INT *) connection);
03186 _suspend_struct[i].listen_dispatch = (INT(*)(INT)) dispatch;
03187 }
03188
03189 if (channel == CH_CLIENT) {
03190 _suspend_struct[i].server_connection =
03191 (RPC_SERVER_CONNECTION *) connection;
03192 _suspend_struct[i].client_dispatch = (INT(*)(INT)) dispatch;
03193 }
03194
03195 if (channel == CH_SERVER) {
03196 _suspend_struct[i].server_acception =
03197 (RPC_SERVER_ACCEPTION *) connection;
03198 _suspend_struct[i].server_dispatch = (INT(*)(INT, int, BOOL)) dispatch;
03199 }
03200
03201 return SS_SUCCESS;
03202 }
03203
03204
03205 INT ss_suspend_get_port(INT * port)
03206
03207
03208
03209
03210
03211
03212
03213
03214
03215
03216
03217
03218
03219
03220
03221
03222
03223
03224
03225
03226 {
03227 INT index, status;
03228
03229 status = ss_suspend_get_index(&index);
03230
03231 if (status != SS_SUCCESS)
03232 return status;
03233
03234 if (!_suspend_struct[index].ipc_port)
03235 ss_suspend_init_ipc(index);
03236
03237 *port = _suspend_struct[index].ipc_port;
03238
03239 return SS_SUCCESS;
03240 }
03241
03242
03243 INT ss_suspend(INT millisec, INT msg)
03244
03245
03246
03247
03248
03249
03250
03251
03252
03253
03254
03255
03256
03257
03258
03259
03260
03261
03262
03263
03264
03265
03266
03267
03268
03269
03270
03271
03272
03273
03274 {
03275 fd_set readfds;
03276 struct timeval timeout;
03277 INT sock, server_socket;
03278 INT index, status, i, return_status;
03279 int size;
03280 struct sockaddr from_addr;
03281 char str[100], buffer[80], buffer_tmp[80];
03282
03283
03284 status = ss_suspend_get_index(&index);
03285
03286 if (status != SS_SUCCESS)
03287 return status;
03288
03289 return_status = SS_TIMEOUT;
03290
03291 do {
03292 FD_ZERO(&readfds);
03293
03294
03295 if (_suspend_struct[index].listen_socket)
03296 FD_SET(_suspend_struct[index].listen_socket, &readfds);
03297
03298
03299 if (_suspend_struct[index].server_acception)
03300 for (i = 0; i < MAX_RPC_CONNECTION; i++) {
03301
03302 sock = _suspend_struct[index].server_acception[i].recv_sock;
03303
03304
03305 if (!sock
03306 || _suspend_struct[index].server_acception[i].tid !=
03307 ss_gettid())
03308 continue;
03309
03310
03311 if (recv_tcp_check(sock) == 0)
03312 FD_SET(sock, &readfds);
03313
03314
03315 else if (msg == 0)
03316 millisec = 0;
03317
03318
03319 sock = _suspend_struct[index].server_acception[i].event_sock;
03320
03321 if (!sock)
03322 continue;
03323
03324
03325 if (recv_event_check(sock) == 0)
03326 FD_SET(sock, &readfds);
03327
03328
03329 else if (msg == 0)
03330 millisec = 0;
03331 }
03332
03333
03334 if (_suspend_struct[index].server_connection) {
03335 sock = _suspend_struct[index].server_connection->recv_sock;
03336 if (sock)
03337 FD_SET(sock, &readfds);
03338 }
03339
03340
03341 if (_suspend_struct[index].ipc_recv_socket)
03342 FD_SET(_suspend_struct[index].ipc_recv_socket, &readfds);
03343
03344 timeout.tv_sec = millisec / 1000;
03345 timeout.tv_usec = (millisec % 1000) * 1000;
03346
03347 do {
03348 if (millisec < 0)
03349 status = select(FD_SETSIZE, &readfds, NULL, NULL, NULL);
03350 else
03351 status = select(FD_SETSIZE, &readfds, NULL, NULL, &timeout);
03352
03353
03354 if (status == -1 && timeout.tv_sec >= WATCHDOG_INTERVAL / 1000)
03355 timeout.tv_sec -= WATCHDOG_INTERVAL / 1000;
03356
03357 } while (status == -1);
03358
03359
03360 if (_suspend_struct[index].listen_socket &&
03361 FD_ISSET(_suspend_struct[index].listen_socket, &readfds)) {
03362 sock = _suspend_struct[index].listen_socket;
03363
03364 if (_suspend_struct[index].listen_dispatch) {
03365 status = _suspend_struct[index].listen_dispatch(sock);
03366 if (status == RPC_SHUTDOWN)
03367 return status;
03368 }
03369 }
03370
03371
03372 if (_suspend_struct[index].server_acception)
03373 for (i = 0; i < MAX_RPC_CONNECTION; i++) {
03374
03375 sock = _suspend_struct[index].server_acception[i].recv_sock;
03376
03377
03378 if (!sock
03379 || _suspend_struct[index].server_acception[i].tid !=
03380 ss_gettid())
03381 continue;
03382
03383 if (recv_tcp_check(sock) || FD_ISSET(sock, &readfds)) {
03384 if (_suspend_struct[index].server_dispatch) {
03385 status =
03386 _suspend_struct[index].server_dispatch(i, sock, msg != 0);
03387 _suspend_struct[index].server_acception[i].last_activity =
03388 ss_millitime();
03389
03390 if (status == SS_ABORT || status == SS_EXIT
03391 || status == RPC_SHUTDOWN)
03392 return status;
03393
03394 return_status = SS_SERVER_RECV;
03395 }
03396 }
03397
03398
03399 sock = _suspend_struct[index].server_acception[i].event_sock;
03400 if (!sock)
03401 continue;
03402
03403 if (recv_event_check(sock) || FD_ISSET(sock, &readfds)) {
03404 if (_suspend_struct[index].server_dispatch) {
03405 status =
03406 _suspend_struct[index].server_dispatch(i, sock, msg != 0);
03407 _suspend_struct[index].server_acception[i].last_activity =
03408 ss_millitime();
03409
03410 if (status == SS_ABORT || status == SS_EXIT
03411 || status == RPC_SHUTDOWN)
03412 return status;
03413
03414 return_status = SS_SERVER_RECV;
03415 }
03416 }
03417 }
03418
03419
03420 if (_suspend_struct[index].server_connection) {
03421 sock = _suspend_struct[index].server_connection->recv_sock;
03422
03423 if (sock && FD_ISSET(sock, &readfds)) {
03424 if (_suspend_struct[index].client_dispatch)
03425 status = _suspend_struct[index].client_dispatch(sock);
03426 else {
03427 status = SS_SUCCESS;
03428 size = recv_tcp(sock, buffer, sizeof(buffer), 0);
03429
03430 if (size <= 0)
03431 status = SS_ABORT;
03432 }
03433
03434 if (status == SS_ABORT) {
03435 sprintf(str, "Server connection broken to %s",
03436 _suspend_struct[index].server_connection->host_name);
03437 cm_msg(MINFO, "ss_suspend", str);
03438
03439
03440 closesocket(_suspend_struct[index].server_connection->send_sock);
03441 closesocket(_suspend_struct[index].server_connection->recv_sock);
03442 closesocket(_suspend_struct[index].server_connection->
03443 event_sock);
03444
03445 memset(_suspend_struct[index].server_connection,
03446 0, sizeof(RPC_CLIENT_CONNECTION));
03447
03448
03449 return SS_ABORT;
03450 }
03451
03452 return_status = SS_CLIENT_RECV;
03453 }
03454 }
03455
03456
03457 if (_suspend_struct[index].ipc_recv_socket &&
03458 FD_ISSET(_suspend_struct[index].ipc_recv_socket, &readfds)) {
03459
03460 size = sizeof(struct sockaddr);
03461 size = recvfrom(_suspend_struct[index].ipc_recv_socket,
03462 buffer, sizeof(buffer), 0, &from_addr,
03463 (int *) &size);
03464
03465
03466 server_socket = 0;
03467 if (_suspend_struct[index].server_acception &&
03468 rpc_get_server_option(RPC_OSERVER_TYPE) != ST_REMOTE)
03469 for (i = 0; i < MAX_RPC_CONNECTION; i++) {
03470 sock = _suspend_struct[index].server_acception[i].send_sock;
03471 if (sock
03472 && _suspend_struct[index].server_acception[i].tid ==
03473 ss_gettid())
03474 server_socket = sock;
03475 }
03476
03477
03478 do {
03479 FD_ZERO(&readfds);
03480 FD_SET(_suspend_struct[index].ipc_recv_socket, &readfds);
03481
03482 timeout.tv_sec = 0;
03483 timeout.tv_usec = 0;
03484
03485 status = select(FD_SETSIZE, &readfds, NULL, NULL, &timeout);
03486
03487 if (status != -1
03488 && FD_ISSET(_suspend_struct[index].ipc_recv_socket,
03489 &readfds)) {
03490 size = sizeof(struct sockaddr);
03491 size =
03492 recvfrom(_suspend_struct[index].ipc_recv_socket, buffer_tmp,
03493 sizeof(buffer_tmp), 0, &from_addr, &size);
03494
03495
03496 if (buffer_tmp[0] != 'B' || strcmp(buffer_tmp, buffer) != 0)
03497 if (_suspend_struct[index].ipc_dispatch)
03498 _suspend_struct[index].ipc_dispatch(buffer_tmp,
03499 server_socket);
03500 }
03501
03502 } while (FD_ISSET(_suspend_struct[index].ipc_recv_socket, &readfds));
03503
03504
03505 if (msg == MSG_BM && buffer[0] == 'B')
03506 return SS_SUCCESS;
03507 if (msg == MSG_ODB && buffer[0] == 'O')
03508 return SS_SUCCESS;
03509
03510
03511 if (_suspend_struct[index].ipc_dispatch)
03512 _suspend_struct[index].ipc_dispatch(buffer, server_socket);
03513
03514 return_status = SS_SUCCESS;
03515 }
03516
03517 } while (millisec < 0);
03518
03519 return return_status;
03520 }
03521
03522
03523 INT ss_resume(INT port, char *message)
03524
03525
03526
03527
03528
03529
03530
03531
03532
03533
03534
03535
03536
03537
03538
03539
03540
03541
03542
03543
03544
03545
03546 {
03547 INT status, index;
03548
03549 if (ss_in_async_routine_flag) {
03550
03551 index = 0;
03552 } else {
03553 status = ss_suspend_get_index(&index);
03554
03555 if (status != SS_SUCCESS)
03556 return status;
03557 }
03558
03559 _suspend_struct[index].bind_addr.sin_port = htons((short) port);
03560
03561 status = sendto(_suspend_struct[index].ipc_send_socket, message,
03562 strlen(message) + 1, 0,
03563 (struct sockaddr *) &_suspend_struct[index].bind_addr,
03564 sizeof(struct sockaddr_in));
03565
03566 if (status != (INT) strlen(message) + 1)
03567 return SS_SOCKET_ERROR;
03568
03569 return SS_SUCCESS;
03570 }
03571
03572
03573
03574
03575
03576
03577
03578
03579
03580 INT send_tcp(int sock, char *buffer, DWORD buffer_size, INT flags)
03581
03582
03583
03584
03585
03586
03587
03588
03589
03590
03591
03592
03593
03594
03595
03596
03597
03598
03599
03600 {
03601 DWORD count;
03602 INT status;
03603
03604
03605
03606 for (count = 0; (INT) count < (INT) buffer_size - NET_TCP_SIZE;) {
03607 status = send(sock, buffer + count, NET_TCP_SIZE, flags);
03608 if (status != -1)
03609 count += status;
03610 else {
03611 cm_msg(MERROR, "send_tcp",
03612 "send(socket=%d,size=%d) returned %d, errno: %d (%s)", sock,
03613 NET_TCP_SIZE, status, errno, strerror(errno));
03614 return status;
03615 }
03616 }
03617
03618 while (count < buffer_size) {
03619 status = send(sock, buffer + count, buffer_size - count, flags);
03620 if (status != -1)
03621 count += status;
03622 else {
03623 cm_msg(MERROR, "send_tcp",
03624 "send(socket=%d,size=%d) returned %d, errno: %d (%s)", sock,
03625 (int) (buffer_size - count), status, errno, strerror(errno));
03626 return status;
03627 }
03628 }
03629
03630 return count;
03631 }
03632
03633
03634 INT recv_string(int sock, char *buffer, DWORD buffer_size, INT millisec)
03635
03636
03637
03638
03639
03640
03641
03642
03643
03644
03645
03646
03647
03648
03649
03650
03651
03652
03653
03654
03655
03656
03657
03658
03659 {
03660 INT i, status;
03661 DWORD n;
03662 fd_set readfds;
03663 struct timeval timeout;
03664
03665 n = 0;
03666 memset(buffer, 0, buffer_size);
03667
03668 do {
03669 if (millisec > 0) {
03670 FD_ZERO(&readfds);
03671 FD_SET(sock, &readfds);
03672
03673 timeout.tv_sec = millisec / 1000;
03674 timeout.tv_usec = (millisec % 1000) * 1000;
03675
03676 do {
03677 status = select(FD_SETSIZE, &readfds, NULL, NULL, &timeout);
03678
03679
03680 if (status == -1 && timeout.tv_sec >= WATCHDOG_INTERVAL / 1000)
03681 timeout.tv_sec -= WATCHDOG_INTERVAL / 1000;
03682
03683 } while (status == -1);
03684
03685 if (!FD_ISSET(sock, &readfds))
03686 break;
03687 }
03688
03689 i = recv(sock, buffer + n, 1, 0);
03690
03691 if (i <= 0)
03692 break;
03693
03694 n++;
03695
03696 if (n >= buffer_size)
03697 break;
03698
03699 } while (buffer[n - 1] && buffer[n - 1] != 10);
03700
03701 return n - 1;
03702 }
03703
03704
03705 INT recv_tcp(int sock, char *net_buffer, DWORD buffer_size, INT flags)
03706
03707
03708
03709
03710
03711
03712
03713
03714
03715
03716
03717
03718
03719
03720
03721
03722
03723
03724
03725
03726
03727
03728
03729
03730
03731
03732
03733
03734
03735 {
03736 INT param_size, n_received, n;
03737 NET_COMMAND *nc;
03738
03739 if (buffer_size < sizeof(NET_COMMAND_HEADER)) {
03740 cm_msg(MERROR, "recv_tcp", "parameters too large for network buffer");
03741 return -1;
03742 }
03743
03744
03745 n_received = 0;
03746 do {
03747 #ifdef OS_UNIX
03748 do {
03749 n = recv(sock, net_buffer + n_received,
03750 sizeof(NET_COMMAND_HEADER), flags);
03751
03752
03753 } while (n == -1 && errno == EINTR);
03754 #else
03755 n = recv(sock, net_buffer + n_received,
03756 sizeof(NET_COMMAND_HEADER), flags);
03757 #endif
03758
03759 if (n <= 0) {
03760 cm_msg(MERROR, "recv_tcp",
03761 "header: recv returned %d, n_received = %d, errno: %d (%s)",
03762 n, n_received, errno, strerror(errno));
03763 return n;
03764 }
03765
03766 n_received += n;
03767
03768 } while (n_received < sizeof(NET_COMMAND_HEADER));
03769
03770
03771
03772 nc = (NET_COMMAND *) net_buffer;
03773 param_size = nc->header.param_size;
03774 n_received = 0;
03775
03776 if (param_size == 0)
03777 return sizeof(NET_COMMAND_HEADER);
03778
03779 do {
03780 #ifdef OS_UNIX
03781 do {
03782 n = recv(sock, net_buffer + sizeof(NET_COMMAND_HEADER) + n_received,
03783 param_size - n_received, flags);
03784
03785
03786 } while (n == -1 && errno == EINTR);
03787 #else
03788 n = recv(sock, net_buffer + sizeof(NET_COMMAND_HEADER) + n_received,
03789 param_size - n_received, flags);
03790 #endif
03791
03792 if (n <= 0) {
03793 cm_msg(MERROR, "recv_tcp",
03794 "param: recv returned %d, n_received = %d, errno: %d (%s)", n,
03795 n_received, errno, strerror(errno));
03796 return n;
03797 }
03798
03799 n_received += n;
03800 } while (n_received < param_size);
03801
03802 return sizeof(NET_COMMAND_HEADER) + param_size;
03803 }
03804
03805
03806 INT send_udp(int sock, char *buffer, DWORD buffer_size, INT flags)
03807
03808
03809
03810
03811
03812
03813
03814
03815
03816
03817
03818
03819
03820
03821
03822
03823
03824
03825
03826
03827
03828
03829 {
03830 INT status;
03831 UDP_HEADER *udp_header;
03832 static char udp_buffer[NET_UDP_SIZE];
03833 static INT serial_number = 0, n_received = 0;
03834 DWORD i, data_size;
03835
03836 udp_header = (UDP_HEADER *) udp_buffer;
03837 data_size = NET_UDP_SIZE - sizeof(UDP_HEADER);
03838
03839
03840
03841
03842
03843 if (buffer_size >= NET_UDP_SIZE / 2 && buffer_size <= data_size) {
03844
03845
03846
03847 if (n_received) {
03848 udp_header->serial_number = UDP_FIRST | n_received;
03849 udp_header->sequence_number = ++serial_number;
03850
03851 send(sock, udp_buffer, n_received + sizeof(UDP_HEADER), flags);
03852 n_received = 0;
03853 }
03854
03855 udp_header->serial_number = UDP_FIRST | buffer_size;
03856 udp_header->sequence_number = ++serial_number;
03857
03858 memcpy(udp_header + 1, buffer, buffer_size);
03859 status =
03860 send(sock, udp_buffer, buffer_size + sizeof(UDP_HEADER), flags);
03861 if (status == (INT) buffer_size + (int) sizeof(UDP_HEADER))
03862 status -= sizeof(UDP_HEADER);
03863
03864 return status;
03865 }
03866
03867
03868
03869
03870
03871 if (buffer_size <= data_size) {
03872
03873 if (buffer_size + n_received < data_size) {
03874 memcpy(udp_buffer + sizeof(UDP_HEADER) + n_received, buffer,
03875 buffer_size);
03876
03877 n_received += buffer_size;
03878 return buffer_size;
03879 }
03880
03881
03882 udp_header->serial_number = UDP_FIRST | n_received;
03883 udp_header->sequence_number = ++serial_number;
03884
03885 status =
03886 send(sock, udp_buffer, n_received + sizeof(UDP_HEADER), flags);
03887
03888 n_received = 0;
03889
03890 memcpy(udp_header + 1, buffer, buffer_size);
03891 n_received = buffer_size;
03892
03893 return buffer_size;
03894 }
03895
03896
03897
03898
03899
03900
03901
03902 if (n_received) {
03903 udp_header->serial_number = UDP_FIRST | n_received;
03904 udp_header->sequence_number = ++serial_number;
03905
03906 send(sock, udp_buffer, n_received + sizeof(UDP_HEADER), flags);
03907 n_received = 0;
03908 }
03909
03910 for (i = 0; i < ((buffer_size - 1) / data_size); i++) {
03911 if (i == 0) {
03912 udp_header->serial_number = UDP_FIRST | buffer_size;
03913 udp_header->sequence_number = ++serial_number;
03914 } else {
03915 udp_header->serial_number = serial_number;
03916 udp_header->sequence_number = i;
03917 }
03918
03919 memcpy(udp_header + 1, buffer + i * data_size, data_size);
03920 send(sock, udp_buffer, NET_UDP_SIZE, flags);
03921 }
03922
03923
03924 udp_header->serial_number = serial_number;
03925 udp_header->sequence_number = i;
03926 memcpy(udp_header + 1, buffer + i * data_size,
03927 buffer_size - i * data_size);
03928 status =
03929 send(sock, udp_buffer,
03930 sizeof(UDP_HEADER) + buffer_size - i * data_size, flags);
03931 if ((DWORD) status == sizeof(UDP_HEADER) + buffer_size - i * data_size)
03932 return buffer_size;
03933
03934 return status;
03935 }
03936
03937
03938 INT recv_udp(int sock, char *buffer, DWORD buffer_size, INT flags)
03939
03940
03941
03942
03943
03944
03945
03946
03947
03948
03949
03950
03951
03952
03953
03954
03955
03956
03957
03958
03959
03960 {
03961 INT i, status;
03962 UDP_HEADER *udp_header;
03963 char udp_buffer[NET_UDP_SIZE];
03964 DWORD serial_number, sequence_number, total_buffer_size;
03965 DWORD data_size, n_received;
03966 fd_set readfds;
03967 struct timeval timeout;
03968
03969 udp_header = (UDP_HEADER *) udp_buffer;
03970 data_size = NET_UDP_SIZE - sizeof(UDP_HEADER);
03971
03972
03973 #ifdef OS_UNIX
03974 do {
03975 i = recv(sock, udp_buffer, NET_UDP_SIZE, flags);
03976
03977
03978 } while (i == -1 && errno == EINTR);
03979 #else
03980 i = recv(sock, udp_buffer, NET_UDP_SIZE, flags);
03981 #endif
03982
03983 start:
03984
03985
03986 while (!(udp_header->serial_number & UDP_FIRST)) {
03987
03988 FD_ZERO(&readfds);
03989 FD_SET(sock, &readfds);
03990
03991 timeout.tv_sec = 0;
03992 timeout.tv_usec = 100000;
03993
03994 do {
03995 status = select(FD_SETSIZE, &readfds, NULL, NULL, &timeout);
03996 } while (status == -1);
03997
03998
03999
04000
04001
04002 if (!FD_ISSET(sock, &readfds))
04003 return 0;
04004
04005 #ifdef OS_UNIX
04006 do {
04007 i = recv(sock, udp_buffer, NET_UDP_SIZE, flags);
04008
04009
04010 } while (i == -1 && errno == EINTR);
04011 #else
04012 i = recv(sock, udp_buffer, NET_UDP_SIZE, flags);
04013 #endif
04014 }
04015
04016
04017 total_buffer_size = udp_header->serial_number & ~UDP_FIRST;
04018 serial_number = udp_header->sequence_number;
04019 sequence_number = 0;
04020
04021 if (total_buffer_size <= data_size) {
04022 if (buffer_size < total_buffer_size) {
04023 memcpy(buffer, udp_header + 1, buffer_size);
04024 return buffer_size;
04025 } else {
04026 memcpy(buffer, udp_header + 1, total_buffer_size);
04027 return total_buffer_size;
04028 }
04029 }
04030
04031
04032 n_received = data_size;
04033
04034 if (buffer_size < data_size) {
04035 memcpy(buffer, udp_header + 1, buffer_size);
04036 return buffer_size;
04037 }
04038
04039 memcpy(buffer, udp_header + 1, data_size);
04040
04041
04042 do {
04043
04044 FD_ZERO(&readfds);
04045 FD_SET(sock, &readfds);
04046
04047 timeout.tv_sec = 0;
04048 timeout.tv_usec = 100000;
04049
04050 do {
04051 status = select(FD_SETSIZE, &readfds, NULL, NULL, &timeout);
04052 } while (status == -1);
04053
04054
04055
04056
04057
04058 if (!FD_ISSET(sock, &readfds))
04059 return 0;
04060
04061 #ifdef OS_UNIX
04062 do {
04063 i = recv(sock, udp_buffer, NET_UDP_SIZE, flags);
04064
04065
04066 } while (i == -1 && errno == EINTR);
04067 #else
04068 i = recv(sock, udp_buffer, NET_UDP_SIZE, flags);
04069 #endif
04070
04071 sequence_number++;
04072
04073
04074 if (udp_header->serial_number != serial_number ||
04075 udp_header->sequence_number != sequence_number)
04076
04077 goto start;
04078
04079
04080 memcpy(buffer + n_received, udp_header + 1, i - sizeof(UDP_HEADER));
04081
04082 n_received += (i - sizeof(UDP_HEADER));
04083
04084 } while (n_received < total_buffer_size);
04085
04086 return n_received;
04087 }
04088
04089
04090
04091 #ifdef OS_MSDOS
04092 #ifdef sopen
04093
04094
04095
04096
04097
04098
04099 #undef sopen
04100
04101 int sopen(const char *path, int access, int shflag, int mode)
04102 {
04103 return open(path, (access) | (shflag), mode);
04104 }
04105
04106 #endif
04107 #endif
04108
04109
04110
04111
04112
04113
04114
04115
04116
04117 INT ss_tape_open(char *path, INT oflag, INT * channel)
04118
04119
04120
04121
04122
04123
04124
04125
04126
04127
04128
04129
04130
04131
04132
04133
04134
04135
04136
04137
04138
04139 {
04140 #ifdef OS_UNIX
04141 struct mtop arg;
04142
04143 cm_enable_watchdog(FALSE);
04144
04145 *channel = open(path, oflag, 0644);
04146
04147 cm_enable_watchdog(TRUE);
04148
04149 if (*channel < 0)
04150 cm_msg(MERROR, "ss_tape_open", strerror(errno));
04151
04152 if (*channel < 0) {
04153 if (errno == EIO)
04154 return SS_NO_TAPE;
04155 if (errno == EBUSY)
04156 return SS_DEV_BUSY;
04157 return errno;
04158 }
04159 #ifdef MTSETBLK
04160
04161 arg.mt_op = MTSETBLK;
04162 arg.mt_count = 0;
04163
04164 ioctl(*channel, MTIOCTOP, &arg);
04165 #endif
04166
04167 #endif
04168
04169 #ifdef OS_WINNT
04170 INT status;
04171 TAPE_GET_MEDIA_PARAMETERS m;
04172
04173 *channel = (INT) CreateFile(path, GENERIC_READ | GENERIC_WRITE, 0,
04174 0, OPEN_EXISTING, 0, NULL);
04175
04176 if (*channel == (INT) INVALID_HANDLE_VALUE) {
04177 status = GetLastError();
04178 if (status == ERROR_SHARING_VIOLATION) {
04179 cm_msg(MERROR, "ss_tape_open", "tape is used by other process");
04180 return SS_DEV_BUSY;
04181 }
04182 if (status == ERROR_FILE_NOT_FOUND) {
04183 cm_msg(MERROR, "ss_tape_open", "tape device \"%s\" doesn't exist",
04184 path);
04185 return SS_NO_TAPE;
04186 }
04187
04188 cm_msg(MERROR, "ss_tape_open", "unknown error %d", status);
04189 return status;
04190 }
04191
04192 status = GetTapeStatus((HANDLE) (*channel));
04193 if (status == ERROR_NO_MEDIA_IN_DRIVE || status == ERROR_BUS_RESET) {
04194 cm_msg(MERROR, "ss_tape_open", "no media in drive");
04195 return SS_NO_TAPE;
04196 }
04197
04198
04199 memset(&m, 0, sizeof(m));
04200 m.BlockSize = TAPE_BUFFER_SIZE;
04201 SetTapeParameters((HANDLE) (*channel), SET_TAPE_MEDIA_INFORMATION, &m);
04202
04203 #endif
04204
04205 return SS_SUCCESS;
04206 }
04207
04208
04209 INT ss_tape_close(INT channel)
04210
04211
04212
04213
04214
04215
04216
04217
04218
04219
04220
04221
04222
04223
04224
04225
04226
04227 {
04228 INT status;
04229
04230 #ifdef OS_UNIX
04231
04232 status = close(channel);
04233
04234 if (status < 0) {
04235 cm_msg(MERROR, "ss_tape_close", strerror(errno));
04236 return errno;
04237 }
04238 #endif
04239
04240 #ifdef OS_WINNT
04241
04242 if (!CloseHandle((HANDLE) channel)) {
04243 status = GetLastError();
04244 cm_msg(MERROR, "ss_tape_close", "unknown error %d", status);
04245 return status;
04246 }
04247 #endif
04248
04249 return SS_SUCCESS;
04250 }
04251
04252
04253 INT ss_tape_status(char *path)
04254
04255
04256
04257
04258
04259
04260
04261
04262
04263
04264
04265
04266
04267
04268
04269
04270 {
04271 #ifdef OS_UNIX
04272 char str[256];
04273
04274 sprintf(str, "mt -f %s status", path);
04275 system(str);
04276 #endif
04277
04278 #ifdef OS_WINNT
04279 INT status, channel;
04280 DWORD size;
04281 TAPE_GET_MEDIA_PARAMETERS m;
04282 TAPE_GET_DRIVE_PARAMETERS d;
04283 double x;
04284
04285 channel = (INT) CreateFile(path, GENERIC_READ | GENERIC_WRITE, 0,
04286 0, OPEN_EXISTING, 0, NULL);
04287
04288 if (channel == (INT) INVALID_HANDLE_VALUE) {
04289 status = GetLastError();
04290 if (status == ERROR_SHARING_VIOLATION) {
04291 cm_msg(MINFO, "ss_tape_status", "tape is used by other process");
04292 return SS_SUCCESS;
04293 }
04294 if (status == ERROR_FILE_NOT_FOUND) {
04295 cm_msg(MINFO, "ss_tape_status", "tape device \"%s\" doesn't exist",
04296 path);
04297 return SS_SUCCESS;
04298 }
04299
04300 cm_msg(MINFO, "ss_tape_status", "unknown error %d", status);
04301 return status;
04302 }
04303
04304
04305 GetTapeParameters((HANDLE) channel, GET_TAPE_DRIVE_INFORMATION, &size,
04306 &d);
04307 GetTapeParameters((HANDLE) channel, GET_TAPE_DRIVE_INFORMATION, &size,
04308 &d);
04309
04310 status = GetTapeStatus((HANDLE) channel);
04311 if (status == ERROR_NO_MEDIA_IN_DRIVE || status == ERROR_BUS_RESET) {
04312 cm_msg(MINFO, "ss_tape_status", "no media in drive");
04313 CloseHandle((HANDLE) channel);
04314 return SS_SUCCESS;
04315 }
04316
04317 GetTapeParameters((HANDLE) channel, GET_TAPE_DRIVE_INFORMATION, &size,
04318 &d);
04319 GetTapeParameters((HANDLE) channel, GET_TAPE_MEDIA_INFORMATION, &size,
04320 &m);
04321
04322 printf("Hardware error correction is %s\n", d.ECC ? "on" : "off");
04323 printf("Hardware compression is %s\n", d.Compression ? "on" : "off");
04324 printf("Tape %s write protected\n", m.WriteProtected ? "is" : "is not");
04325
04326 if (d.FeaturesLow & TAPE_DRIVE_TAPE_REMAINING) {
04327 x = ((double) m.Remaining.LowPart +
04328 (double) m.Remaining.HighPart * 4.294967295E9)
04329 / 1024.0 / 1000.0;
04330 printf("Tape capacity remaining is %d MB\n", (int) x);
04331 } else
04332 printf("Tape capacity is not reported by tape\n");
04333
04334 CloseHandle((HANDLE) channel);
04335
04336 #endif
04337
04338 return SS_SUCCESS;
04339 }
04340
04341
04342 INT ss_tape_write(INT channel, void *pdata, INT count)
04343
04344
04345
04346
04347
04348
04349
04350
04351
04352
04353
04354
04355
04356
04357
04358
04359
04360
04361
04362
04363 {
04364 #ifdef OS_UNIX
04365 INT status;
04366
04367 do {
04368 status = write(channel, pdata, count);
04369
04370
04371
04372
04373 } while (status == -1 && errno == EINTR);
04374
04375 if (status != count) {
04376 cm_msg(MERROR, "ss_tape_write", strerror(errno));
04377
04378 if (errno == EIO)
04379 return SS_IO_ERROR;
04380 else
04381 return SS_TAPE_ERROR;
04382 }
04383 #endif
04384
04385 #ifdef OS_WINNT
04386 INT status;
04387 DWORD written;
04388
04389 WriteFile((HANDLE) channel, pdata, count, &written, NULL);
04390 if (written != (DWORD) count) {
04391 status = GetLastError();
04392 cm_msg(MERROR, "ss_tape_write", "error %d", status);
04393
04394 return SS_IO_ERROR;
04395 }
04396 #endif
04397
04398 return SS_SUCCESS;
04399 }
04400
04401
04402 INT ss_tape_read(INT channel, void *pdata, INT * count)
04403
04404
04405
04406
04407
04408
04409
04410
04411
04412
04413
04414
04415
04416
04417
04418
04419
04420
04421
04422 {
04423 #ifdef OS_UNIX
04424 INT n, status;
04425
04426 do {
04427 n = read(channel, pdata, *count);
04428 } while (n == -1 && errno == EINTR);
04429
04430 if (n == -1) {
04431 if (errno == ENOSPC || errno == EIO)
04432 status = SS_END_OF_TAPE;
04433 else {
04434 if (n == 0 && errno == 0)
04435 status = SS_END_OF_FILE;
04436 else {
04437 cm_msg(MERROR, "ss_tape_read",
04438 "unexpected tape error: n=%d, errno=%d\n", n, errno);
04439 status = errno;
04440 }
04441 }
04442 } else
04443 status = SS_SUCCESS;
04444 *count = n;
04445
04446 return status;
04447
04448 #elif defined(OS_WINNT)
04449
04450 INT status;
04451 DWORD read;
04452
04453 if (!ReadFile((HANDLE) channel, pdata, *count, &read, NULL)) {
04454 status = GetLastError();
04455 if (status == ERROR_NO_DATA_DETECTED)
04456 status = SS_END_OF_TAPE;
04457 else if (status == ERROR_FILEMARK_DETECTED)
04458 status = SS_END_OF_FILE;
04459 else if (status == ERROR_MORE_DATA)
04460 status = SS_SUCCESS;
04461 else
04462 cm_msg(MERROR, "ss_tape_read",
04463 "unexpected tape error: n=%d, errno=%d\n", read, status);
04464 } else
04465 status = SS_SUCCESS;
04466
04467 *count = read;
04468 return status;
04469
04470 #else
04471
04472 return SS_SUCCESS;
04473
04474 #endif
04475 }
04476
04477
04478 INT ss_tape_write_eof(INT channel)
04479
04480
04481
04482
04483
04484
04485
04486
04487
04488
04489
04490
04491
04492
04493
04494
04495
04496 {
04497 INT status;
04498
04499 #ifdef OS_UNIX
04500 struct mtop arg;
04501
04502 arg.mt_op = MTWEOF;
04503 arg.mt_count = 1;
04504
04505 cm_enable_watchdog(FALSE);
04506
04507 status = ioctl(channel, MTIOCTOP, &arg);
04508
04509 cm_enable_watchdog(TRUE);
04510
04511 if (status < 0) {
04512 cm_msg(MERROR, "ss_tape_write_eof", strerror(errno));
04513 return errno;
04514 }
04515 #endif
04516
04517 #ifdef OS_WINNT
04518
04519 TAPE_GET_DRIVE_PARAMETERS d;
04520 DWORD size;
04521
04522 size = sizeof(TAPE_GET_DRIVE_PARAMETERS);
04523 GetTapeParameters((HANDLE) channel, GET_TAPE_DRIVE_INFORMATION, &size,
04524 &d);
04525
04526 if (d.FeaturesHigh & TAPE_DRIVE_WRITE_FILEMARKS)
04527 status = WriteTapemark((HANDLE) channel, TAPE_FILEMARKS, 1, FALSE);
04528 else if (d.FeaturesHigh & TAPE_DRIVE_WRITE_LONG_FMKS)
04529 status =
04530 WriteTapemark((HANDLE) channel, TAPE_LONG_FILEMARKS, 1, FALSE);
04531 else if (d.FeaturesHigh & TAPE_DRIVE_WRITE_SHORT_FMKS)
04532 status =
04533 WriteTapemark((HANDLE) channel, TAPE_SHORT_FILEMARKS, 1, FALSE);
04534 else
04535 cm_msg(MERROR, "ss_tape_write_eof",
04536 "tape doesn't support writing of filemarks");
04537
04538 if (status != NO_ERROR) {
04539 cm_msg(MERROR, "ss_tape_write_eof", "unknown error %d", status);
04540 return status;
04541 }
04542 #endif
04543
04544 return SS_SUCCESS;
04545 }
04546
04547
04548 INT ss_tape_fskip(INT channel, INT count)
04549
04550
04551
04552
04553
04554
04555
04556
04557
04558
04559
04560
04561
04562
04563
04564
04565
04566
04567 {
04568 INT status;
04569
04570 #ifdef OS_UNIX
04571 struct mtop arg;
04572
04573 if (count > 0)
04574 arg.mt_op = MTFSF;
04575 else
04576 arg.mt_op = MTBSF;
04577 arg.mt_count = abs(count);
04578
04579 cm_enable_watchdog(FALSE);
04580
04581 status = ioctl(channel, MTIOCTOP, &arg);
04582
04583 cm_enable_watchdog(TRUE);
04584
04585 if (status < 0) {
04586 cm_msg(MERROR, "ss_tape_fskip", strerror(errno));
04587 return errno;
04588 }
04589 #endif
04590
04591 #ifdef OS_WINNT
04592
04593 status = SetTapePosition((HANDLE) channel, TAPE_SPACE_FILEMARKS, 0,
04594 (DWORD) count, 0, FALSE);
04595
04596 if (status == ERROR_END_OF_MEDIA)
04597 return SS_END_OF_TAPE;
04598
04599 if (status != NO_ERROR) {
04600 cm_msg(MERROR, "ss_tape_fskip", "error %d", status);
04601 return status;
04602 }
04603 #endif
04604
04605 return SS_SUCCESS;
04606 }
04607
04608
04609 INT ss_tape_rskip(INT channel, INT count)
04610
04611
04612
04613
04614
04615
04616
04617
04618
04619
04620
04621
04622
04623
04624
04625
04626
04627
04628 {
04629 INT status;
04630
04631 #ifdef OS_UNIX
04632 struct mtop arg;
04633
04634 if (count > 0)
04635 arg.mt_op = MTFSR;
04636 else
04637 arg.mt_op = MTBSR;
04638 arg.mt_count = abs(count);
04639
04640 cm_enable_watchdog(FALSE);
04641
04642 status = ioctl(channel, MTIOCTOP, &arg);
04643
04644 cm_enable_watchdog(TRUE);
04645
04646 if (status < 0) {
04647 cm_msg(MERROR, "ss_tape_rskip", strerror(errno));
04648 return errno;
04649 }
04650 #endif
04651
04652 #ifdef OS_WINNT
04653
04654 status = SetTapePosition((HANDLE) channel, TAPE_SPACE_RELATIVE_BLOCKS, 0,
04655 (DWORD) count, 0, FALSE);
04656 if (status != NO_ERROR) {
04657 cm_msg(MERROR, "ss_tape_rskip", "error %d", status);
04658 return status;
04659 }
04660 #endif
04661
04662 return CM_SUCCESS;
04663 }
04664
04665
04666 INT ss_tape_rewind(INT channel)
04667
04668
04669
04670
04671
04672
04673
04674
04675
04676
04677
04678
04679
04680
04681
04682
04683
04684 {
04685 INT status;
04686
04687 #ifdef OS_UNIX
04688 struct mtop arg;
04689
04690 arg.mt_op = MTREW;
04691 arg.mt_count = 0;
04692
04693 cm_enable_watchdog(FALSE);
04694
04695 status = ioctl(channel, MTIOCTOP, &arg);
04696
04697 cm_enable_watchdog(TRUE);
04698
04699 if (status < 0) {
04700 cm_msg(MERROR, "ss_tape_rewind", strerror(errno));
04701 return errno;
04702 }
04703 #endif
04704
04705 #ifdef OS_WINNT
04706
04707 status = SetTapePosition((HANDLE) channel, TAPE_REWIND, 0, 0, 0, FALSE);
04708 if (status != NO_ERROR) {
04709 cm_msg(MERROR, "ss_tape_rewind", "error %d", status);
04710 return status;
04711 }
04712 #endif
04713
04714 return CM_SUCCESS;
04715 }
04716
04717
04718 INT ss_tape_spool(INT channel)
04719
04720
04721
04722
04723
04724
04725
04726
04727
04728
04729
04730
04731
04732
04733
04734
04735
04736 {
04737 INT status;
04738
04739 #ifdef OS_UNIX
04740 struct mtop arg;
04741
04742 #ifdef MTEOM
04743 arg.mt_op = MTEOM;
04744 #else
04745 arg.mt_op = MTSEOD;
04746 #endif
04747 arg.mt_count = 0;
04748
04749 cm_enable_watchdog(FALSE);
04750
04751 status = ioctl(channel, MTIOCTOP, &arg);
04752
04753 cm_enable_watchdog(TRUE);
04754
04755 if (status < 0) {
04756 cm_msg(MERROR, "ss_tape_rewind", strerror(errno));
04757 return errno;
04758 }
04759 #endif
04760
04761 #ifdef OS_WINNT
04762
04763 status =
04764 SetTapePosition((HANDLE) channel, TAPE_SPACE_END_OF_DATA, 0, 0, 0,
04765 FALSE);
04766 if (status != NO_ERROR) {
04767 cm_msg(MERROR, "ss_tape_spool", "error %d", status);
04768 return status;
04769 }
04770 #endif
04771
04772 return CM_SUCCESS;
04773 }
04774
04775
04776 INT ss_tape_mount(INT channel)
04777
04778
04779
04780
04781
04782
04783
04784
04785
04786
04787
04788
04789
04790
04791
04792
04793
04794 {
04795 INT status;
04796
04797 #ifdef OS_UNIX
04798 struct mtop arg;
04799
04800 #ifdef MTLOAD
04801 arg.mt_op = MTLOAD;
04802 #else
04803 arg.mt_op = MTNOP;
04804 #endif
04805 arg.mt_count = 0;
04806
04807 cm_enable_watchdog(FALSE);
04808
04809 status = ioctl(channel, MTIOCTOP, &arg);
04810
04811 cm_enable_watchdog(TRUE);
04812
04813 if (status < 0) {
04814 cm_msg(MERROR, "ss_tape_mount", strerror(errno));
04815 return errno;
04816 }
04817 #endif
04818
04819 #ifdef OS_WINNT
04820
04821 status = PrepareTape((HANDLE) channel, TAPE_LOAD, FALSE);
04822 if (status != NO_ERROR) {
04823 cm_msg(MERROR, "ss_tape_mount", "error %d", status);
04824 return status;
04825 }
04826 #endif
04827
04828 return CM_SUCCESS;
04829 }
04830
04831
04832 INT ss_tape_unmount(INT channel)
04833
04834
04835
04836
04837
04838
04839
04840
04841
04842
04843
04844
04845
04846
04847
04848
04849
04850 {
04851 INT status;
04852
04853 #ifdef OS_UNIX
04854 struct mtop arg;
04855
04856 #ifdef MTOFFL
04857 arg.mt_op = MTOFFL;
04858 #else
04859 arg.mt_op = MTUNLOAD;
04860 #endif
04861 arg.mt_count = 0;
04862
04863 cm_enable_watchdog(FALSE);
04864
04865 status = ioctl(channel, MTIOCTOP, &arg);
04866
04867 cm_enable_watchdog(TRUE);
04868
04869 if (status < 0) {
04870 cm_msg(MERROR, "ss_tape_unmount", strerror(errno));
04871 return errno;
04872 }
04873 #endif
04874
04875 #ifdef OS_WINNT
04876
04877 status = PrepareTape((HANDLE) channel, TAPE_UNLOAD, FALSE);
04878 if (status != NO_ERROR) {
04879 cm_msg(MERROR, "ss_tape_unmount", "error %d", status);
04880 return status;
04881 }
04882 #endif
04883
04884 return CM_SUCCESS;
04885 }
04886
04887
04888 INT ss_tape_get_blockn(INT channel)
04889
04890
04891
04892
04893
04894
04895
04896
04897 {
04898 INT status;
04899
04900 #ifdef OS_UNIX
04901 struct mtpos arg;
04902
04903 cm_enable_watchdog(FALSE);
04904 status = ioctl(channel, MTIOCPOS, &arg);
04905 cm_enable_watchdog(TRUE);
04906 if (status < 0) {
04907 if (errno == EIO)
04908 return 0;
04909 else {
04910 cm_msg(MERROR, "ss_tape_get_blockn", strerror(errno));
04911 return -errno;
04912 }
04913 }
04914 return (arg.mt_blkno);
04915
04916 #endif
04917
04918 #ifdef OS_WINNT
04919 TAPE_GET_MEDIA_PARAMETERS media;
04920 unsigned long size;
04921
04922 status =
04923 GetTapeParameters((HANDLE) channel, GET_TAPE_MEDIA_INFORMATION,
04924 &size, &media);
04925 return (media.PartitionCount);
04926 #endif
04927 }
04928
04929
04930
04931
04932
04933
04934
04935
04936
04937
04938 double ss_disk_free(char *path)
04939
04940
04941
04942
04943
04944
04945
04946
04947
04948
04949
04950
04951
04952
04953
04954 {
04955 #ifdef OS_UNIX
04956 #if defined(OS_OSF1)
04957 struct statfs st;
04958 statfs(path, &st, sizeof(st));
04959 return (double) st.f_bavail * st.f_bsize;
04960 #elif defined(OS_LINUX)
04961 struct statfs st;
04962 statfs(path, &st);
04963 return (double) st.f_bavail * st.f_bsize;
04964 #elif defined(OS_SOLARIS)
04965 struct statvfs st;
04966 statvfs(path, &st);
04967 return (double) st.f_bavail * st.f_bsize;
04968 #elif defined(OS_IRIX)
04969 struct statfs st;
04970 statfs(path, &st, sizeof(struct statfs), 0);
04971 return (double) st.f_bfree * st.f_bsize;
04972 #else
04973 struct fs_data st;
04974 statfs(path, &st);
04975 return (double) st.fd_otsize * st.fd_bfree;
04976 #endif
04977
04978 #elif defined(OS_WINNT)
04979 DWORD SectorsPerCluster;
04980 DWORD BytesPerSector;
04981 DWORD NumberOfFreeClusters;
04982 DWORD TotalNumberOfClusters;
04983 char str[80];
04984
04985 strcpy(str, path);
04986 if (strchr(str, ':') != NULL) {
04987 *(strchr(str, ':') + 1) = 0;
04988 strcat(str, DIR_SEPARATOR_STR);
04989 GetDiskFreeSpace(str, &SectorsPerCluster, &BytesPerSector,
04990 &NumberOfFreeClusters, &TotalNumberOfClusters);
04991 } else
04992 GetDiskFreeSpace(NULL, &SectorsPerCluster, &BytesPerSector,
04993 &NumberOfFreeClusters, &TotalNumberOfClusters);
04994
04995 return (double) NumberOfFreeClusters *SectorsPerCluster * BytesPerSector;
04996 #else
04997
04998 return 1e9;
04999
05000 #endif
05001 }
05002
05003 #if defined(OS_ULTRIX) || defined(OS_WINNT)
05004 int fnmatch(const char *pat, const char *str, const int flag)
05005 {
05006 while (*str != '\0') {
05007 if (*pat == '*') {
05008 pat++;
05009 if ((str = strchr(str, *pat)) == NULL)
05010 return -1;
05011 }
05012 if (*pat == *str) {
05013 pat++;
05014 str++;
05015 } else
05016 return -1;
05017 }
05018 if (*pat == '\0')
05019 return 0;
05020 else
05021 return -1;
05022 }
05023 #endif
05024
05025 #ifdef OS_WINNT
05026 HANDLE pffile;
05027 LPWIN32_FIND_DATA lpfdata;
05028 #endif
05029 INT ss_file_find(char *path, char *pattern, char **plist)
05030
05031
05032
05033
05034
05035
05036
05037
05038
05039
05040
05041
05042
05043
05044
05045
05046
05047 {
05048 int i;
05049 #ifdef OS_UNIX
05050 DIR *dir_pointer;
05051 struct dirent *dp;
05052
05053 if ((dir_pointer = opendir(path)) == NULL)
05054 return 0;
05055 *plist = (char *) malloc(MAX_STRING_LENGTH);
05056 i = 0;
05057 for (dp = readdir(dir_pointer); dp != NULL; dp = readdir(dir_pointer)) {
05058 if (fnmatch(pattern, dp->d_name, 0) == 0) {
05059 *plist = (char *) realloc(*plist, (i + 1) * MAX_STRING_LENGTH);
05060 strncpy(*plist + (i * MAX_STRING_LENGTH), dp->d_name,
05061 strlen(dp->d_name));
05062 *(*plist + (i * MAX_STRING_LENGTH) + strlen(dp->d_name)) = '\0';
05063 i++;
05064 seekdir(dir_pointer, telldir(dir_pointer));
05065 }
05066 }
05067 closedir(dir_pointer);
05068 #endif
05069 #ifdef OS_WINNT
05070 char str[255];
05071 int first;
05072
05073 strcpy(str, path);
05074 strcat(str, "\\");
05075 strcat(str, pattern);
05076 first = 1;
05077 i = 0;
05078 lpfdata = (WIN32_FIND_DATA *) malloc(sizeof(WIN32_FIND_DATA));
05079 *plist = (char *) malloc(MAX_STRING_LENGTH);
05080 pffile = FindFirstFile(str, lpfdata);
05081 if (pffile == INVALID_HANDLE_VALUE)
05082 return 0;
05083 first = 0;
05084 *plist = (char *) realloc(*plist, (i + 1) * MAX_STRING_LENGTH);
05085 strncpy(*plist + (i * MAX_STRING_LENGTH), lpfdata->cFileName,
05086 strlen(lpfdata->cFileName));
05087 *(*plist + (i * MAX_STRING_LENGTH) + strlen(lpfdata->cFileName)) = '\0';
05088 i++;
05089 while (FindNextFile(pffile, lpfdata)) {
05090 *plist = (char *) realloc(*plist, (i + 1) * MAX_STRING_LENGTH);
05091 strncpy(*plist + (i * MAX_STRING_LENGTH), lpfdata->cFileName,
05092 strlen(lpfdata->cFileName));
05093 *(*plist + (i * MAX_STRING_LENGTH) + strlen(lpfdata->cFileName)) =
05094 '\0';
05095 i++;
05096 }
05097 free(lpfdata);
05098 #endif
05099 return i;
05100 }
05101
05102 INT ss_file_remove(char *path)
05103
05104
05105
05106
05107
05108
05109
05110
05111
05112
05113
05114
05115
05116
05117
05118 {
05119 return remove(path);
05120 }
05121
05122 double ss_file_size(char *path)
05123
05124
05125
05126
05127
05128
05129
05130
05131
05132
05133
05134
05135
05136
05137
05138 {
05139 struct stat stat_buf;
05140
05141
05142 stat(path, &stat_buf);
05143 return (double) stat_buf.st_size;
05144 }
05145
05146 double ss_disk_size(char *path)
05147
05148
05149
05150
05151
05152
05153
05154
05155
05156
05157
05158
05159
05160
05161
05162 {
05163 #ifdef OS_UNIX
05164 #if defined(OS_OSF1)
05165 struct statfs st;
05166 statfs(path, &st, sizeof(st));
05167 return (double) st.f_blocks * st.f_fsize;
05168 #elif defined(OS_LINUX)
05169 struct statfs st;
05170 statfs(path, &st);
05171 return (double) st.f_blocks * st.f_bsize;
05172 #elif defined(OS_SOLARIS)
05173 struct statvfs st;
05174 statvfs(path, &st);
05175 if (st.f_frsize > 0)
05176 return (double) st.f_blocks * st.f_frsize;
05177 else
05178 return (double) st.f_blocks * st.f_bsize;
05179 #elif defined(OS_ULTRIX)
05180 struct fs_data st;
05181 statfs(path, &st);
05182 return (double) st.fd_btot * 1024;
05183 #elif defined(OS_IRIX)
05184 struct statfs st;
05185 statfs(path, &st, sizeof(struct statfs), 0);
05186 return (double) st.f_blocks * st.f_bsize;
05187 #else
05188 #error ss_disk_size not defined for this OS
05189 #endif
05190 #endif
05191
05192 #ifdef OS_WINNT
05193 DWORD SectorsPerCluster;
05194 DWORD BytesPerSector;
05195 DWORD NumberOfFreeClusters;
05196 DWORD TotalNumberOfClusters;
05197 char str[80];
05198
05199 strcpy(str, path);
05200 if (strchr(str, ':') != NULL) {
05201 *(strchr(str, ':') + 1) = 0;
05202 strcat(str, DIR_SEPARATOR_STR);
05203 GetDiskFreeSpace(str, &SectorsPerCluster, &BytesPerSector,
05204 &NumberOfFreeClusters, &TotalNumberOfClusters);
05205 } else
05206 GetDiskFreeSpace(NULL, &SectorsPerCluster, &BytesPerSector,
05207 &NumberOfFreeClusters, &TotalNumberOfClusters);
05208
05209 return (double) TotalNumberOfClusters *SectorsPerCluster *
05210 BytesPerSector;
05211 #endif
05212
05213 return 1e9;
05214 }
05215
05216
05217
05218
05219
05220
05221
05222
05223
05224 void ss_clear_screen()
05225
05226
05227
05228
05229
05230
05231
05232
05233
05234
05235
05236
05237
05238
05239
05240
05241 {
05242 #ifdef OS_WINNT
05243
05244 HANDLE hConsole;
05245 COORD coordScreen = { 0, 0 };
05246 BOOL bSuccess;
05247 DWORD cCharsWritten;
05248 CONSOLE_SCREEN_BUFFER_INFO csbi;
05249 DWORD dwConSize;
05250
05251 hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
05252
05253
05254 bSuccess = GetConsoleScreenBufferInfo(hConsole, &csbi);
05255 dwConSize = csbi.dwSize.X * csbi.dwSize.Y;
05256
05257
05258 bSuccess = FillConsoleOutputCharacter(hConsole, (TCHAR) ' ',
05259 dwConSize, coordScreen,
05260 &cCharsWritten);
05261
05262
05263 bSuccess = SetConsoleCursorPosition(hConsole, coordScreen);
05264 return;
05265
05266 #endif
05267 #if defined(OS_UNIX) || defined(OS_VXWORKS) || defined(OS_VMS)
05268 printf("\033[2J");
05269 #endif
05270 #ifdef OS_MSDOS
05271 clrscr();
05272 #endif
05273 }
05274
05275
05276 void ss_set_screen_size(int x, int y)
05277
05278
05279
05280
05281
05282
05283
05284
05285
05286
05287
05288
05289
05290
05291
05292
05293 {
05294 #ifdef OS_WINNT
05295
05296 HANDLE hConsole;
05297 COORD coordSize;
05298
05299 coordSize.X = (short) x;
05300 coordSize.Y = (short) y;
05301 hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
05302 SetConsoleScreenBufferSize(hConsole, coordSize);
05303
05304 #endif
05305 }
05306
05307
05308 void ss_printf(INT x, INT y, const char *format, ...)
05309
05310
05311
05312
05313
05314
05315
05316
05317
05318
05319
05320
05321
05322
05323
05324
05325
05326
05327
05328
05329 {
05330 char str[256];
05331 va_list argptr;
05332
05333 va_start(argptr, format);
05334 vsprintf(str, (char *) format, argptr);
05335 va_end(argptr);
05336
05337 #ifdef OS_WINNT
05338 {
05339 HANDLE hConsole;
05340 COORD dwWriteCoord;
05341 DWORD cCharsWritten;
05342
05343 hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
05344
05345 dwWriteCoord.X = (short) x;
05346 dwWriteCoord.Y = (short) y;
05347
05348 WriteConsoleOutputCharacter(hConsole, str, strlen(str),
05349 dwWriteCoord, &cCharsWritten);
05350 }
05351
05352 #endif
05353
05354 #if defined(OS_UNIX) || defined(OS_VXWORKS) || defined(OS_VMS)
05355 printf("\033[%1d;%1d;H", y + 1, x + 1);
05356 printf(str);
05357 fflush(stdout);
05358 #endif
05359
05360 #ifdef OS_MSDOS
05361 gotoxy(x + 1, y + 1);
05362 cputs(str);
05363 #endif
05364 }
05365
05366
05367 char *ss_getpass(char *prompt)
05368
05369
05370
05371
05372
05373
05374
05375
05376
05377
05378
05379
05380
05381
05382
05383
05384 {
05385 static char password[32];
05386
05387 printf(prompt);
05388 memset(password, 0, sizeof(password));
05389
05390 #ifdef OS_UNIX
05391 return (char *) getpass("");
05392 #elif defined(OS_WINNT)
05393 {
05394 HANDLE hConsole;
05395 DWORD nCharsRead;
05396
05397 hConsole = GetStdHandle(STD_INPUT_HANDLE);
05398 SetConsoleMode(hConsole, ENABLE_LINE_INPUT);
05399 ReadConsole(hConsole, password, sizeof(password), &nCharsRead, NULL);
05400 SetConsoleMode(hConsole, ENABLE_LINE_INPUT | ENABLE_ECHO_INPUT |
05401 ENABLE_PROCESSED_INPUT | ENABLE_MOUSE_INPUT);
05402 printf("\n");
05403
05404 if (password[strlen(password) - 1] == '\r')
05405 password[strlen(password) - 1] = 0;
05406
05407 return password;
05408 }
05409 #elif defined(OS_MSDOS)
05410 {
05411 char c, *ptr;
05412
05413 ptr = password;
05414 while ((c = getchar()) != EOF && c != '\n')
05415 *ptr++ = c;
05416 *ptr = 0;
05417
05418 printf("\n");
05419 return password;
05420 }
05421 #else
05422 {
05423 ss_gets(password, 32);
05424 return password;
05425 }
05426 #endif
05427 }
05428
05429
05430 INT ss_getchar(BOOL reset)
05431
05432
05433
05434
05435
05436
05437
05438
05439
05440
05441
05442
05443
05444
05445
05446
05447
05448
05449
05450 {
05451 #ifdef OS_UNIX
05452
05453 static BOOL init = FALSE;
05454 static struct termios save_termios;
05455 struct termios buf;
05456 int i, fd;
05457 char c[3];
05458
05459 if (_daemon_flag)
05460 return 0;
05461
05462 fd = fileno(stdin);
05463
05464 if (reset) {
05465 if (init)
05466 tcsetattr(fd, TCSAFLUSH, &save_termios);
05467 init = FALSE;
05468 return 0;
05469 }
05470
05471 if (!init) {
05472 tcgetattr(fd, &save_termios);
05473 memcpy(&buf, &save_termios, sizeof(buf));
05474
05475 buf.c_lflag &= ~(ECHO | ICANON | IEXTEN);
05476
05477 buf.c_iflag &= ~(ICRNL | INPCK | ISTRIP | IXON);
05478
05479 buf.c_cflag &= ~(CSIZE | PARENB);
05480 buf.c_cflag |= CS8;
05481
05482 buf.c_cc[VMIN] = 0;
05483 buf.c_cc[VTIME] = 0;
05484
05485 tcsetattr(fd, TCSAFLUSH, &buf);
05486 init = TRUE;
05487 }
05488
05489 memset(c, 0, 3);
05490 i = read(fd, c, 1);
05491
05492 if (i == 0)
05493 return 0;
05494
05495
05496 if (c[0] == 27) {
05497 i = read(fd, c, 2);
05498 if (i == 0)
05499 return 27;
05500
05501
05502 if (c[1] < 65)
05503 read(fd, c, 1);
05504
05505
05506 switch (c[1]) {
05507 case 49:
05508 return CH_HOME;
05509 case 50:
05510 return CH_INSERT;
05511 case 51:
05512 return CH_DELETE;
05513 case 52:
05514 return CH_END;
05515 case 53:
05516 return CH_PUP;
05517 case 54:
05518 return CH_PDOWN;
05519 case 65:
05520 return CH_UP;
05521 case 66:
05522 return CH_DOWN;
05523 case 67:
05524 return CH_RIGHT;
05525 case 68:
05526 return CH_LEFT;
05527 }
05528 }
05529
05530
05531 if (c[0] == 127)
05532 return CH_BS;
05533
05534 return c[0];
05535
05536 #elif defined(OS_WINNT)
05537
05538 static BOOL init = FALSE;
05539 static INT repeat_count = 0;
05540 static INT repeat_char;
05541 HANDLE hConsole;
05542 DWORD nCharsRead;
05543 INPUT_RECORD ir;
05544 OSVERSIONINFO vi;
05545
05546
05547 vi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
05548 GetVersionEx(&vi);
05549
05550 if (vi.dwPlatformId != VER_PLATFORM_WIN32_NT) {
05551
05552 int c;
05553
05554 if (!kbhit())
05555 return 0;
05556
05557 c = getch();
05558 if (c == 224) {
05559 c = getch();
05560 switch (c) {
05561 case 71:
05562 return CH_HOME;
05563 case 72:
05564 return CH_UP;
05565 case 73:
05566 return CH_PUP;
05567 case 75:
05568 return CH_LEFT;
05569 case 77:
05570 return CH_RIGHT;
05571 case 79:
05572 return CH_END;
05573 case 80:
05574 return CH_DOWN;
05575 case 81:
05576 return CH_PDOWN;
05577 case 82:
05578 return CH_INSERT;
05579 case 83:
05580 return CH_DELETE;
05581 }
05582 }
05583 return c;
05584 }
05585
05586 hConsole = GetStdHandle(STD_INPUT_HANDLE);
05587
05588 if (reset) {
05589 SetConsoleMode(hConsole, ENABLE_LINE_INPUT | ENABLE_ECHO_INPUT |
05590 ENABLE_PROCESSED_INPUT | ENABLE_MOUSE_INPUT);
05591 init = FALSE;
05592 return 0;
05593 }
05594
05595 if (!init) {
05596 SetConsoleMode(hConsole, ENABLE_PROCESSED_INPUT);
05597 init = TRUE;
05598 }
05599
05600 if (repeat_count) {
05601 repeat_count--;
05602 return repeat_char;
05603 }
05604
05605 PeekConsoleInput(hConsole, &ir, 1, &nCharsRead);
05606
05607 if (nCharsRead == 0)
05608 return 0;
05609
05610 ReadConsoleInput(hConsole, &ir, 1, &nCharsRead);
05611
05612 if (ir.EventType != KEY_EVENT)
05613 return ss_getchar(0);
05614
05615 if (!ir.Event.KeyEvent.bKeyDown)
05616 return ss_getchar(0);
05617
05618 if (ir.Event.KeyEvent.wRepeatCount > 1) {
05619 repeat_count = ir.Event.KeyEvent.wRepeatCount - 1;
05620 repeat_char = ir.Event.KeyEvent.uChar.AsciiChar;
05621 return repeat_char;
05622 }
05623
05624 if (ir.Event.KeyEvent.uChar.AsciiChar)
05625 return ir.Event.KeyEvent.uChar.AsciiChar;
05626
05627 if (ir.Event.KeyEvent.dwControlKeyState & (ENHANCED_KEY)) {
05628 switch (ir.Event.KeyEvent.wVirtualKeyCode) {
05629 case 33:
05630 return CH_PUP;
05631 case 34:
05632 return CH_PDOWN;
05633 case 35:
05634 return CH_END;
05635 case 36:
05636 return CH_HOME;
05637 case 37:
05638 return CH_LEFT;
05639 case 38:
05640 return CH_UP;
05641 case 39:
05642 return CH_RIGHT;
05643 case 40:
05644 return CH_DOWN;
05645 case 45:
05646 return CH_INSERT;
05647 case 46:
05648 return CH_DELETE;
05649 }
05650
05651 return ir.Event.KeyEvent.wVirtualKeyCode;
05652 }
05653
05654 return ss_getchar(0);
05655
05656 #elif defined(OS_MSDOS)
05657
05658 int c;
05659
05660 if (!kbhit())
05661 return 0;
05662
05663 c = getch();
05664 if (!c) {
05665 c = getch();
05666 switch (c) {
05667 case 71:
05668 return CH_HOME;
05669 case 72:
05670 return CH_UP;
05671 case 73:
05672 return CH_PUP;
05673 case 75:
05674 return CH_LEFT;
05675 case 77:
05676 return CH_RIGHT;
05677 case 79:
05678 return CH_END;
05679 case 80:
05680 return CH_DOWN;
05681 case 81:
05682 return CH_PDOWN;
05683 case 82:
05684 return CH_INSERT;
05685 case 83:
05686 return CH_DELETE;
05687 }
05688 }
05689 return c;
05690
05691 #else
05692 return -1;
05693 #endif
05694 }
05695
05696
05697 char *ss_gets(char *string, int size)
05698
05699
05700
05701
05702
05703
05704
05705
05706
05707
05708
05709
05710
05711
05712
05713
05714
05715
05716 {
05717 char *p;
05718
05719 do {
05720 p = fgets(string, size, stdin);
05721 } while (p == NULL);
05722
05723
05724 if (strlen(p) > 0 && p[strlen(p) - 1] == '\n')
05725 p[strlen(p) - 1] = 0;
05726
05727 return p;
05728 }
05729
05730
05731
05732
05733
05734
05735
05736
05737
05738 INT ss_directio_give_port(INT start, INT end)
05739 {
05740 #ifdef OS_WINNT
05741
05742
05743
05744 OSVERSIONINFO vi;
05745 HANDLE hdio = 0;
05746 DWORD buffer[] = { 6, 0, 0, 0 };
05747 DWORD size;
05748
05749 vi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
05750 GetVersionEx(&vi);
05751
05752
05753 if (vi.dwPlatformId == VER_PLATFORM_WIN32_NT) {
05754 hdio =
05755 CreateFile("\\\\.\\directio", GENERIC_READ, FILE_SHARE_READ, NULL,
05756 OPEN_EXISTING, 0, NULL);
05757 if (hdio == INVALID_HANDLE_VALUE) {
05758 printf
05759 ("hyt1331.c: Cannot access IO ports (No DirectIO driver installed)\n");
05760 return -1;
05761 }
05762
05763
05764 buffer[1] = start;
05765 buffer[2] = end;
05766 if (!DeviceIoControl(hdio, (DWORD) 0x9c406000, &buffer, sizeof(buffer),
05767 NULL, 0, &size, NULL))
05768 return -1;
05769 }
05770
05771 return SS_SUCCESS;
05772 #else
05773 return SS_SUCCESS;
05774 #endif
05775 }
05776
05777
05778 INT ss_directio_lock_port(INT start, INT end)
05779 {
05780 #ifdef OS_WINNT
05781
05782
05783
05784 OSVERSIONINFO vi;
05785 HANDLE hdio;
05786 DWORD buffer[] = { 7, 0, 0, 0 };
05787 DWORD size;
05788
05789 vi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
05790 GetVersionEx(&vi);
05791
05792
05793 if (vi.dwPlatformId == VER_PLATFORM_WIN32_NT) {
05794 hdio =
05795 CreateFile("\\\\.\\directio", GENERIC_READ, FILE_SHARE_READ, NULL,
05796 OPEN_EXISTING, 0, NULL);
05797 if (hdio == INVALID_HANDLE_VALUE) {
05798 printf
05799 ("hyt1331.c: Cannot access IO ports (No DirectIO driver installed)\n");
05800 return -1;
05801 }
05802
05803
05804 buffer[1] = start;
05805 buffer[2] = end;
05806 if (!DeviceIoControl(hdio, (DWORD) 0x9c406000, &buffer, sizeof(buffer),
05807 NULL, 0, &size, NULL))
05808 return -1;
05809 }
05810
05811 return SS_SUCCESS;
05812 #else
05813 return SS_SUCCESS;
05814 #endif
05815 }
05816
05817
05818
05819
05820
05821
05822
05823
05824
05825 INT ss_syslog(const char *message)
05826
05827
05828
05829
05830
05831
05832
05833
05834
05835
05836
05837
05838
05839
05840
05841
05842 {
05843 #ifdef OS_UNIX
05844 static BOOL init = FALSE;
05845
05846 if (!init) {
05847 #ifdef OS_ULTRIX
05848 openlog("MIDAS", LOG_PID);
05849 #else
05850 openlog("MIDAS", LOG_PID, LOG_USER);
05851 #endif
05852 init = TRUE;
05853 }
05854
05855 syslog(LOG_DEBUG, message);
05856 return SS_SUCCESS;
05857 #elif defined(OS_WINNT)
05858
05859
05860
05861
05862
05863
05864
05865
05866
05867
05868
05869
05870
05871
05872
05873
05874
05875
05876
05877
05878
05879
05880
05881
05882
05883
05884
05885
05886
05887
05888 return SS_SUCCESS;
05889
05890 #else
05891
05892 return SS_SUCCESS;
05893
05894 #endif
05895 }
05896
05897
05898
05899
05900
05901
05902
05903
05904 #define bin_to_ascii(c) ((c)>=38?((c)-38+'a'):(c)>=12?((c)-12+'A'):(c)+'.')
05905
05906 char *ss_crypt(char *buf, char *salt)
05907
05908
05909
05910
05911
05912
05913
05914
05915
05916
05917
05918
05919
05920
05921
05922
05923
05924
05925
05926 {
05927 int i, seed;
05928 static char enc_pw[13];
05929
05930 memset(enc_pw, 0, sizeof(enc_pw));
05931 enc_pw[0] = salt[0];
05932 enc_pw[1] = salt[1];
05933
05934 for (i = 0; i < 8 && buf[i]; i++)
05935 enc_pw[i + 2] = buf[i];
05936 for (; i < 8; i++)
05937 enc_pw[i + 2] = 0;
05938
05939 seed = 123;
05940 for (i = 2; i < 13; i++) {
05941 seed = 5 * seed + 27 + enc_pw[i];
05942 enc_pw[i] = (char) bin_to_ascii(seed & 0x3F);
05943 }
05944
05945 return enc_pw;
05946 }
05947
05948
05949 #endif
05950
05951
05952
05953
05954
05955